DRY neden önemlidir?


81

Oldukça basit, neden tüm ihtiyacım için çalışan kod ve tüm ihtiyacım olan aynı küçük birkaç tweaks ile birkaç kez tekrarlanırsa ölçeklenebilir veriler yazmak isteyeyim?

Bunu daha sonra herhangi bir zamanda tekrar düzenlemem gerekmiyor.

Sadece gitmek için daha az iş gibi görünüyor ...

function doStuff1(){/*.a.*/}
function doStuff2(){/*.b.*/}
function doStuff3(){/*.c.*/}

Ve eğer bir şey eklemem gerekirse ...

function doStuff4(){/*.d.*/}

Ve kaldırmam gerekirse, kaldırırım.

Bunların hepsini sadece verileri besleyebildiğim ve tüm vakalarla başa çıkabildiğim tek bir ileri kalıpta nasıl yapacağımı bulmak ve daha önce yaşayacağım gibi hissetmediğim bir sürü değişiklik yapmak zor. yapmak.

Çabuk kesilmiş gibi göründüğünde neden KURU olmalısınız? Yapıştırma işi çok daha az işe yarayacak mı?


11
çünkü doğru yaptığınızda kuru hala daha hızlıdır, ya da bir hata yaparsanız. diğerlerini de etkiler
Daniel Little

97
"Yakında herhangi bir zamanda bunu tekrar düzenlemem gerekmiyor" - umabilirsiniz, ama muhtemelen burada bir hata yapıyorsunuzdur. Yine o kodu işe gidiyor, ama eğer Ve değil çok yakında, sadece kötü şeyler yapacaktır; yinelemelerin nerede olduğunu unutacaksınız ve yinelemeler zekice fakat hain tutarsızlıklar artacak. Klasikleri alıntılamak için "Kodunuzu koruyacak kişi nerede yaşadığını bilen tehlikeli bir manyakmış gibi yazınız".
9000,

14
Bununla hemen hemen özetleyebileceğinizi düşünüyorum: Tek bir değişiklik noktasının korunması daha kolaydır.
Falcon,

17
Buna kendiniz cevap veremiyorsanız, dünyadaki gelişim ve bakım konusunda daha gerçek bir deneyim edinmelisiniz.
David Heffernan

15
@Hayne, sanki bir anda dehşet içinde milyonlarca programcı ağlamış gibi, kaynağında büyük bir rahatsızlık hissetmiştim.
gizli

Yanıtlar:


121

Kendinizi tekrarlarsanız, bakım sorunları oluşturabilirsiniz. DoStuff1-3 modelinde hepsi benzer şekilde yapılandırılmış bir koda sahipse ve bir sorunu çözdüyseniz, sorunu başka yerlerde çözmeyi kolayca unutabilirsiniz. Ayrıca, ele almak için yeni bir vaka eklemek zorunda kalırsanız, her yere kopya yapıştırmak yerine farklı parametreleri tek bir işleve geçirebilirsiniz.

Bununla birlikte, DRY akıllı programcılar tarafından sıklıkla aşırı bir duruma getirilir. Bazen kendini tekrar etmemek için soyutlamalar yapmalısın, bu yüzden takım arkadaşlarının onları takip edemeyeceği kadar geniş. Bazen iki şeyin yapısı sadece belli belirsizdir ancak yeterince farklıdır. DoStuff1-4, kendilerini tekrar etmemek için yeniden yapılandırmanın, doğal olmayan kodlar yazmanıza veya ekibinizin size göz kamaştırmasına neden olacak akıllı kodlama backflipslerine maruz kalmanıza neden olacak kadar farklıysa, o zaman kendinizi tekrarlamanız uygun olabilir. Doğal olmayan yollardan kendimi birkaç kez tekrarlamamak için geriye doğru eğildim ve son üründen pişman oldum.

Ben her zaman DRY'nin yanına geliyorum, nadir bir durumda, okunabilirlikteki faydaların birden fazla yerde bir hatayı düzeltmeyi unutan birinin riskine değeceğini düşündüğümde kendimi tekrar ediyorum.

Bu tavsiyeyi dikkate alarak, durumunuzdaki gibi

birkaç küçük tweaks ile aynı işlemi birkaç kez tekrarlayın

Durumunda kendimi tekrar etmemek için kesinlikle çok çalışırdım. Minimal "tweaks" olduğu varsayılarak - davranışı etkileyen farklı parametrelerle veya farklı alt görevler gerçekleştirmek için belki de dependancy enjekte edilerek ele alınabilir.

Çabuk kesilmiş gibi göründüğünde neden KURU olmalısınız? Yapıştırma işi çok daha az işe yarayacak mı?

Ünlü son sözler. Küçük bir mühendis, birinin yapmasını / düzeltilmesini / düzeltilmesini sağladığında ve diğerlerinin var olduğunun bile farkına varmadığını düşünerek pişman olacaksınız. Hilarity doğar. Çoğunlukla mide ekşimesi oluşmaz. Her kod satırı daha maliyetlidir. Bu kadar çok tekrarlanan fonksiyonla kaç tane kod yolunu test etmeniz gerekir? Eğer bir işlev varsa, sadece bir ana yolu birkaç davranış değişikliği ile test etmeniz gerekir. Kopyalanırsa her doStuff'ı ayrı ayrı test etmeniz gerekir. Birini özleyeceğiniz ihtimaller vardır ve bir müşterinin istenmeyen bir hatası olabilir ve gelen kutunuzda istenmeyen bazı e-postalar olabilir.


2
Er, sadece açık olmak gerekirse, kuru önerme değilim, kötü, bu soru daha çok şeytanların savunucusu. Gerçekten mantıklı bir cevap arıyorum kes + paste + tweak kodunun iyi olduğunu düşünen insanlarla bağlantı kurabilirim.
gizli

2
Söylendiği gibi, cevabınızı DRY'deki her iki başarısızlığı da kapsadığı için en çok seviyorum: rahatsız etmemek ve üstesinden gelmek ve aynı zamanda etkileri açıklamak. - Hatalar için okunabilirliği feda etmekle ilgili bir noktada, tekrarlayan kodun, belirttiğiniz nedenlerden dolayı daha az okunabilir olduğunu, bazı şeyleri kaybetmenin kolay olduğunu savunuyorum.
gizli

16
Bir kolay DRY tuzağının altını çizerdim: benzer kod birleştirildi. İşlevsel olarak ilgisiz, ancak çok benzer bir koda sahip olan iki kullanım durumunuz varsa, ikisi birleştirmek kolaydır, çünkü DRY iyidir . Ne yazık ki, bir kişinin evrimleşmesi gerektiğinde, sık sık kendinizi bir kez daha fonksiyonu bölmek zorunda kalmanın hoş olmayan görevini bulursunuz ve ardından tüm çağrı sitelerine girersiniz ve hangisinin burada çağırılması gerektiğini dikkatlice düşünün ... Örnek: LLVM yapısal tiplendirme (tüm benzer tipler bir araya getirilir) IR'yi tekrar orijinal koda eşleştirmeyi imkansız kılar.
Matthieu M.

1
Bingo. İki veya daha fazla kod parçası değişecekse ve değişiklikler tüm parçalar için her zaman aynı olacaksa, birleştirilmeleri gerekir. Diğerlerinden farklı bir şekilde değişmesi gereken hiçbir parça birleştirilmemelidir. Kod hiç değişmeyecekse, birleştirilip birleştirilmemesi önemli değildir. Değişikliklerin kilitlenip kilitlenmediği sorusu, söz konusu kodun boyutundan çok daha önemlidir.
supercat

1
@ MatthieuM bu biraz haksız bir örnek. LLVM, optimizasyon olarak yapısal tipleme uyguluyor ; yani, LLVM millet, performans yararları için anlaşılması zor bir IR bedeli ödemeye karar verdi. KURU, genellikle bir sürdürülebilirlik konusudur, ancak bu durumda, sürdürülebilirliği azaltmak için açıkça kasıtlı bir karardı.
Benjamin Hodgson

47

Çünkü DRY daha sonra daha az çalışacak.


KURU: (Kendinizi Tekrarlama)

Bir fonksiyon tartışıyor.

def log(arg):
    print(arg)

C&P: (Kopyala ve Yapıştır)

26 gazilyon temelde aynı şeyi yapıyor ancak 2 karakter farkı var.

def logA():
    print('a')

def logB():
    print('b')

...ad infinitum...

Tam olarak ne yazdığını belirlemek için baskımızı güncellemeye ne dersiniz?

KURU:

def log(arg):
    print(arg + "Printed from process foo")

Bitti.

Cı & P:

Geri dönüp her bir işlevi değiştirmelisiniz .


Sence hangisi hata ayıklamak daha kolay olur?


10
Ayrıca, yinelenen işlevlere sahip olduğunuz kadar benzer test paketi de yazmanız gerekir.
9000,

Kavramı yeterince açıkladınız, ancak pratikte hiç kimse, bu şekilde değil, bu şekilde değil, hiç bir şekilde gazillion işlevleriyle tanımladığınız şeyi yapmaz.
Robert Harvey,

@Robert umarım olmaz! Konsepti ve bunun neden iyi bir şey olabileceğini daha iyi açıklamaya çalışmak için çok basit bir görev seçtim.
John

11
@Robert - En makaleyi bir okudum thedailywtf.com ;) - bunu sağlayacaktı kim orada bazı vardır
HorusKol

1
@ 9000 Test takımlarınız yoksa: p (ki bazı projelerde aslında sık sık olabilir ... ne yazık ki ...)
Svish

16

Çünkü , örneğinize uygulanır:

  • + okunabilirlik

    Daha az kod genellikle daha az gürültüye dönüşür . (her zaman değil...)

  • + esneklik

    Davranışını değiştirmek doStuffXzorunda kalsaydın, kendini ya da kim yazdıysa onu öldürmek istersin.

  • + genişletilebilirlik

    Farklı bölümleri seçtiğiniz bir veri yapısına çıkardıysanız ve daha sonra bir genel jeneriği çağırırken yinelemeyi doStuffseçtiyseniz, veri yapınıza yeni bir giriş yapmak istediğiniz bir satırı ekleyebilir veya bir tane kaldırabilirsiniz. Davranışı değiştirmek sadece düzenleme anlamına gelecektir doStuff. Bakımı daha kolaydır .

  • + maliyet verimliliği

    Buradaki daha az kod :

    • => daha az gelişme => düşük maliyet
    • => hatalar için daha az olasılık => daha az destek süresi => düşük maliyet
  • + (mümkün) yönetilen optimizasyon

    Dile bağlı olarak, derleyici / tercüman, jenerikin doStuffher zaman hemen hemen aynı şeyleri sık sık birbiri ardına çektiğini belirleme şansına sahip olabilir ve satır içi ya da onu optimize etmeye çalışabilir . Muhtemelen X varyasyonları için olmazdı doStuffX.

  • + test ve kalite

    Test etmek daha kolay: Test doStuffetmek gerekiyor ve hepsi bu. Tam olarak değil, ama bu zaten daha fazlasını kapsar . Yalnızca GÇ beklentileri farklı koşullar altında değişiklik gösterir ve test edilmeleri gerekir, ancak test edilmesinin çok daha kolay ve tüm değişkenliklerinden daha kolay tutulurdoStuffX .

Genel Bu daha hesapları sıçramalı kodu ve bir iyileştirilmiş geliştirme verimliliği takımınız için, ve öyle çok iyi uygulamalarından biri için yardımcı daha sağlam ve güvenilir bir yazılım üretmek.


13

Diğer herkes, bakım kodunu yinelenen kodla açıklamada harika bir iş çıkardığı için şunu söyleyeyim:

Programlamanın çoğu, sadece anı olanı değil geleceği düşünmenizi gerektirir. Kopyala ve yapıştır işleminin artık daha kolay olduğunu söylüyorsunuz, ancak bu ifadenin kısa sürede tekrar düzenlemek zorunda kalmayacağımı ifade ediyorum " doğru dürüst olmadığınızı gösteriyor. Evet, kendinize biraz zaman kazandırabilirsiniz. Hızlı ve kirli kopyala / yapıştır, ancak bunu yaparken acil probleminizin ötesine bakamayacağınızı ve yarın hakkında düşünemeyeceğinizi gösteriyorsunuz, asla bu kodu tekrar gözden geçirmeniz gerekmeyeceğinden emin misiniz? Hata yok? Bir sonraki özellik grubunun uygulanması gerektiğinde% 100 garanti verebilir misiniz? Yarın için sorunlar var ve bugün tasarlanırken dikkat etmeniz gerekiyor.

Tabii ki, kopyala / yapıştır gerekli olacak zamanlar vardır. Bir UI geliştiricisi olarak, DRY ilkesini ihlal etmem gereken zamanlar olduğunu gördüm. Berbat bir durumda, ne zaman olursa olsun onu kandırıyorum ve çok şükür, nadir. Ama yok olur.

Aradaki fark, DRY'yi ihlal ederken, bunu yapmak için çok zorlayıcı bir nedene sahip olmanız gerektiği ve bu ifadenin, hepsini düz bir kalıp haline getirmenin gerçekten onlardan biri olmadığını anlamak daha zor . Çok büyük bir zaman sıkıntısı yaşamadığınız ve önümüzdeki birkaç saat içinde patronunuzun bir şeyler almak için çığlık atmadığı veya işinizi kaybedeceğiniz sürece, bunun geçerli bir gerekçe olduğunu sanmıyorum.

Bunu yanlış anlama: Seni kastetmeye ya da cezalandırmaya çalışmıyorum, ama zihniyetinin yanlış olduğunu görmeye çalış. Programcılar gelecekteki tembelliklere yatırım yapar; KURU, bunu başarmanın bir yoludur. Bugün yaptığınız işin zor bir tasarım problemini çözmesi yarın işe yarayacak.


Bir patronun “halletmek ya da kovulmak” olduğunu söyleyeceğinden emin değilim, DRY'yi ihlal etmek için harika bir neden. Teknik borç, ne zaman doğru yapacak vaktin var, gerçekten zaman kazandıran, vb.
gizli

1
@Incognito, biraz ironik olmaya çalışıyordum :)
bedwyr

7

Bunu daha sonra herhangi bir zamanda tekrar düzenlemem gerekmiyor.

Eğer bu gerçekten doğruysa, o zaman ondan kurtulabilirsiniz, ancak daha çok, bakımı gereken kod üzerinde çalışamayacaksınız. Bu, işlevselliği genişletmek, hataları düzeltmek ve diğer iyileştirmeler anlamına gelir. Aynı kodda 10 farklı yerde küçük değişiklikler varsa ve bir gün bu koda döndüğünde ve bir değişiklik yapman gerekiyorsa, şimdi aynı değişikliği 10 farklı yerde yapma konusunda hata yapma eğilimin var (Maalesef, orada 11 yerdeydin, birini unuttun ve şimdi bir böceğin var)

Hangi sorunu çözmeye çalıştığınızı genelleştirebiliyorsanız, kodunuzu genişletmek ve hatalar çıkarsa düzeltmek için daha kolay hale getirebilirsiniz.


Güzel cevap, ama ondan kaçabilsem bile, peki benden sonra onu koruyacak zavallı sap ne olacak? ).
gizli

Bakın: "bakımı yapılmaması gereken kod üzerinde çalışmayacağınızdan daha sık" :)
Alex

O zaman bile, sadece kopyalayıp yapıştırdığınız şey% 100 hatasız mükemmellik ise geçerlidir. Ve öyle değil ve olabileceğini düşünmekten vazgeç.
Dan Ray,

Geçmişte bir şeyleri kopyalayıp yapıştırdığımı itiraf edeceğim, ancak hiçbir zaman bir günden fazla saklayacağım hiçbir şey için. Bazen sadece hızlı ve kirli bir atma komut dosyası gerekir.
Alex,

6

Başka bir sorunun cevabında belirttiğim gibi benim yaklaşımım şudur:

  1. Belli bir problemi ilk çözdüğümde, hallettim.
  2. İkincisinde (yani benzer bir sorunu çözdüğümde) düşünüyorum: hm, belki kendimi tekrarlıyorum ama şimdilik hızlı bir kopyala ve yapıştır uygulamasına geçeceğim.
  3. Üçüncü kez düşünüyorum: hm, kendimi tekrar ediyorum -> genel yap!

Yani 2'ye kadar, başka bir prensip (YAGNI), DRY'yi kazanır. Fakat 3'ten başlayarak (ya da gerçekten tembel olursam 4'üm!) Buna ihtiyacım olacak gibi görünüyor ve DRY'yi izliyorum.

Güncelleme

Son deneyimimden bazı fikirler. Başka bir ekip tarafından geliştirilen A ve B iki bileşenini ürünümüze uyarlamak / entegre etmek zorunda kaldım. Birincisi: A ve B'nin iki bileşeni birbirine çok benziyor, bu yüzden biraz farklı bir mimariye sahip oldukları gerçeğinden rahatsız oldum. İkincisi: Onları uyarlamak zorunda kaldım, böylece alt sınıfları kullanmaktan ve gerçekten ihtiyacım olanı geçersiz kılmaktan memnun olurdum.

Bu yüzden bu iki bileşeni yeniden düzenlemeye başladım (her biri yaklaşık 8 C ++ sınıfından oluşuyor): Hem A hem de B için ortak bir mimariye sahip olmak ve sonra da alt sınıfları tanımlayarak ihtiyaç duyduğumuz özellikleri eklemek istedim. Bu şekilde iki yeni bileşenimiz A 've B' mevcut olanlardan türemiş olacaktı.

İki hafta sonra mevcut koddan ortak ve iyi tanımlanmış bir yapı elde etmeye çalıştıktan ve günlük toplantılarımızda çok az ilerleme kaydettiğimi açıklamak zorunda kaldıktan sonra, orijinal kodun çok dağınık olduğunu açıklamak zorunda kaldım, patronumla konuştum. Bu iki yeni A 've B bileşeninden daha fazlasına ihtiyaç duymayacağımızı gözlemledik (bunlardan dördü veya altısı olmayacaktı, sadece ikisi).

Tamam, öyleyse öyle: Büyük bir kopya yaptım ve A ve B sınıflarını yeniden adlandırdım ve kodun kopyasını uyarlamaya başladım. İki hafta içinde çalışmaya başladım (şimdi hala hata onarımı yapıyorum).

Avantajları: Neredeyse bitmiş bir işlevselliğe sahibiz ve tüm hataları düzelttik. A ve B'nin tüm yeniden düzenleme ve test işlemlerini gerçekleştirdik

Dezavantajları: İki hafta önce diğer takım A ve B tarafından kullanılan başka bir C bileşenini değiştirdiler. Bu, düzeltmemiz gereken yeni bir hatayı ortaya çıkardı. Eğer A 've B' kodlarının çoğunu A ve B ile paylaşmış olsaydı, bu ekstra iş muhtemelen gereksiz olurdu.

Yani: kod çoğaltma her zaman tehlikelidir. Ben her zaman takas bulma meselesi olduğunu düşünüyorum ve çoğu zaman kolay değildir.


5

Açıklığa kavuşturmak için, bunu diğer cevapların hiçbirinde bulamadığım için:

KURU , her türlü bilginin tekrarlanmasını azaltmayı amaçlayan bir yazılım geliştirme ilkesidir .

Her bilgi parçasının bir sistem içinde tek, açık ve net bir temsiline sahip olması gerekir.

Andy Hunt ve Dave Thomas tarafından belirtildiği gibi DRY prensibi kodun tekrarlanmasını önlemeyle sınırlı değildir. Ayrıca, kod oluşturma ve tüm otomasyon işlemlerini savunur . İronik olarak, kod üretmenin sonuçları yinelenen kod bile olabilir ...

Diğer cevaplarda neden zaten ayrıntılı bir şekilde açıklanmasının nedeni, ancak Falcon'un yorumu IMHO'yu yeterince iyi özetliyor:

Tek bir değişiklik noktasının korunması daha kolaydır.


Vay canına, etiketin içinde bazı veriler olduğunu düşündüm. Oraya biraz bilgi koyacağım.
gizli

3

Çok fazla kuru gibi bir şey var. Bu olduğunda, bir noktada faktoring koduna (1) izin vermek için yeterince benzer görünen iki kavram daha sonra ayrı uygulamaları hak edecek kadar farklı olabilir.

Başka bir deyişle, DRY ve gevşek bağlanma bazen çatışır. DoStuff1 ve arkadaşlarının yazılımın her yeni sürümünde birbirinden ayrılmalarını beklerseniz, kodlarını çoğaltmak tamam olur.

Tecrübelerime göre, yazılımınızın gelecekte nereye gittiğini değerlendirmek zor olabilir ve bu nedenle, DRY genellikle güvenli bir seçimdir.

Aşırı "kurutulmuş" olan kod tipik olarak karmaşık kontrol akışına ve çok fazla parametreye sahiptir. Başlangıçta basit bir fonksiyon olan şey daha sonra ekstra bir parametre tarafından kontrol edilen yeni bir işlevselliği desteklemek için genişletildi. İki veya üç yinelemeden sonra, işlev artık sürdürülemez. Bir ayarda meydana gelen bir hatayı düzelttikten sonra diğer ayarlara yeni hatalar eklersiniz.

Kod kalitesinin, kod geliştikçe sık sık azaldığı anlaşılabilir, ancak vücutta eğer varsa spagetti ile çok parametreli bir fonksiyonun iyi niyetli ancak kötü yürütülen bir refactoring çabası sonucu olduğu durumlarını gördüm.

(1) "kod" kelimesini kullanıyorum, ancak bu tasarım için de geçerli.


Spektrumun daha az görülen ucu olduğu için "çok fazla kuru" bir örnek vermek yararlı olacaktır.
Gizli

@Incognito: Cevabımı düzenledim. Somut bir örnek yok ama umarım demek istediğim yeterince açıktır.
Joh

2

DRY ile ilişkisel veritabanı dünyasındaki problemlerden bahsetmek zorundayım. Veritabanları, küme tabanlı mantığı ve sorgulanabilir sorguları kullanarak hızlı ve iyi performans gösterecek şekilde tasarlanmıştır. KURU ilkeleri genellikle geliştiricinin Sargable olmayan sorgular yazmasına veya birden fazla durumda varolan kodu kullanmak için Satır Yankılanan Satır mantığını kullanmasına neden olur. NEMLENDİRME ve performans optimizasyonu sık sık olasılıklıdır ve veritabanı dünyasında, performans genellikle bakımdan daha kritiktir. Bu, DRY prensiplerini hiç kullanmamanız gerektiği anlamına gelmez, sadece veritabanının genel kullanılabilirliğini nasıl etkileyeceğini bilmeniz gerektiği anlamına gelmez. Uygulama geliştiricileri ilk önce DRY ve ikinci performans, veritabanı geliştiricileri ilk önce veri bütünlüğü, ikinci performans, üçüncü verilerin güvenliği (performans ve güvenlik bazı sistemlerde yer değiştirebilir).

Genel olarak, veritabanına koyduğunuz soyutlama katmanlarının ne kadar yavaş olduklarını sorguladığını fark ettim. Veri tabanı programlarını kendileri tasarlayan insanlara, geliştiricilerin veritabanının performansını iyi etkilemeden DRY kullanmalarına izin vermek için daha iyi bir iş yapmalarını istemedim demiyorum, ancak bu düzeyde veritabanı yazılımı tasarlamıyorum , belki de soyutlama ve veritabanındaki performans arasındaki çatışmayı sandığımdan daha zordur. Ancak, halihazırda yapıldıkları gibi sistemlerle çalışmak zorundayız. DRY ilkelerinin, aynı zamanda performansı düşürmeyecek (ve yıllar içinde daha iyi bir hale gelmiş ancak hala sorunlu) gelecek sürümlerde daha iyi uygulanmasını isteyebiliriz, ancak bu arada, DRY'nin bu veritabanı için doğru hareket olup olmadığını düşünmeliyiz. şu anda.

Ancak, KURU ilkesinin yerine getirilmesini sağlamak için kullanmak istediğiniz özellikler çoğu zaman veritabanı için büyük sorunlara yol açan özelliklerdir. Asla DRY kullanmam demiyorum ama onunla aşırıya kaçma.

Neden bahsettiğimden örnekler. Ayda bir kez bir milyon kaydın veri alımını yapmanız gerekir. Kayıtlar, önceden kaydedilmiş bir proc'u arayarak kullanıcı arayüzü üzerinden manuel olarak eklenebilir. Bu işlem, tek bir kayıt içe aktarma işlemi için tasarlandığından, her seferinde yalnızca bir kayıt ekler. Ek kodunu iki yerde bulundurmamak için DRY özelliğini kullanarak, ihtiyaç duyduğunuz set tabanlı içe aktarmaları yazmak yerine proc'u tekrar tekrar aramak için bir imleç yazabilirsiniz. İçe aktarma süresi, set tabanlı mantığı kullanarak alacağı 30 dakikadan 18 saate kadar sürer. Şimdi bu durumda DRY'ye bağlı kalmanın doğru yolu procun katıksız kayıt ithalatını işlemesi için düzeltilmesi olacaktır. Ne yazık ki, bir proke (db arka ucuna bağlı olarak) bir dizi göndermek genellikle imkansızdır veya çok zordur ve proc'u değiştirerek uygulamayı sonlandırırsınız.

DRY prensiplerini uygulamak için skaler fonksiyonlar ve tablo değerli fonksiyonlar da kullanılır ve yine de özellikle indekslerin faydalı olmasını önleyecek şekilde kullanmanız gerekirse performansı ciddi şekilde etkileyebilir.

Görüşler, DRY'yi uygulamak için de iyidir. Bununla birlikte, DRY'yi, başka görünümleri çağıran görünümleri çağıran görünümleri kullanarak uygularsanız, sorguların yük altında zaman aşımına uğrayacağı noktaya çabucak ulaşırsınız. Aslında, sonunda sadece üçe ihtiyaç duyduğunuzda milyonlarca kayıttan oluşan veri kümeleri oluşturmaya ihtiyaç duyabilirsiniz. Dolayısıyla, DRY'yi uygulamak için karmaşık bir birleştirme kümesinin tek düzey bir görünümü mükemmel olabilir (tüm finansal raporlamanın aynı temel tablo kümesini ve belirli şeylerin hesaplamalarını kullandığından emin olmak için kullandığımız bir tane var). ve bir performans karışıklığı yaratıp yaratmadığınızı düşünmeniz gerekir.


1

Cevabımın kilit noktalarını yukarıda göremiyorum, işte burada. DRY'ye karşı bir kural kadar bakma.bir şey yapıyorum. Bu şekilde ifade edilebilir, ancak gerçekten oldukça farklı ve olumlu bir amaca hizmet edebilir. Durmak, düşünmek ve daha iyi bir cevap bulmak için bir sinyal. Daha iyi bir çözüm tasarlamak için fırsatlar aramamda beni zorluyor. Kodumda kötü bir kokunun güzel yanı, tasarımımı yeniden düşünmeme neden oluyor ve daha iyi yapmamı sağlıyor. DRY sadece bir itty bitty sözdizimi ihlali ile ilgili değildir. Modülerleşmem için beni zorluyor. Bileşen yapmam için beni zorluyor. Bana kaba kuvvet ve cehalet yerine şablonlar ve kod oluşturma hakkında düşünmemi hatırlatıyor. Otomasyonumu otomatikleştirmek için biraz zaman bulmam gerektiğini anlamama yardımcı oluyor. Sizi asil bir yaşam tarzına götürür! Nitpicky eski sıkıcı detaylarından ziyade zamanınızı daha serin yeni şeyler yaparak geçirmenize yardımcı olur. Size iyi görgü, iyi nefes ve sağlıklı bir yaşam tarzı verir! Belki biraz sapmışım cilalarım ....


DRY'nin benim üzerimde çok farklı etkileri var, ancak bunlar sizin üzerindeki etkileri ise, "durmak, düşünmek ve daha iyi bir cevap bulmak için bir sinyal" olma felsefesini ve zorlu olanı seviyorum.
n611x007

1

Eski geliştiricilerin bazılarının DRY'yi hiç umursamadığı eski bir eski projem var. Bu yüzden kod kodunun tamamı GetSystemTimeAsString (), LogToFile () ve diğer pek çok şey gibi yardımcı yöntemlerle karışıktı. Bazı yöntemler özel ihtiyaçlara göre biraz özelleştirildi, ancak çoğu sadece kopyalayıp yapıştırın.

Ne yazık ki yöntemlerden bazıları, bazı durumlarda strcpy () gibi güvensiz şeyler kullanarak, char dizisi gibi ince hatalara sahipti.

Bu yüzden tüm kod parçalarını bulmak, uyumlaştırmak ve hataları düzeltmek gerçek bir PITA idi. Ve biz hala bir şeyleri uyumlu hale getiriyoruz ve düzeltiyoruz.

Asla bilemezsiniz, ilk yönteminizde bir hata yaptıysanız ve daha sonra birkaç kez düzeltmeniz gerekiyorsa, çünkü kopyaladığınızdan. Ve eğer bazı yöntemleri daha sonra kullanmak istiyorsanız, kod tabanındaki 5 yöntemden hangisinin sizin durumunuz için hangisi olduğunu nasıl bildiniz? Yani sadece bir tane kopyalayın, özelleştirin ve işte yeniden başlıyor ...



1

"Kendini tekrar etme" cümlesi biraz fazla basit. Önemli olan “iki bağımsız yerde bir tane potansiyel olarak değiştirilebilecek bilgiden kaçının ”.

Bir programın her biri üç woozlu olan widget'ları işlemesi gerekiyorsa ve formun birçok döngüsü

for (i=0; i<3; i++)
  thisWidget.processWoozle(i);

o zaman, aletlerin üç tabanca içermesi bekleniyor beklentisi, bu halkaların her birine kaplanacaktı ve kodun her parça başına başka bir tabanca sayısına uyacak şekilde güncellenmesi zor olabilirdi. Buna karşılık, eğer biri söyleseydi

#define WOOZLES_PER_WIDGET 3

ve her döngü yeniden yazıldı

for (i=0; i<WOOZLES_PER_WIDGET; i++) ...

böyle bir tasarım , widget başına woole sayısını değiştirmeyi çok kolaylaştırabilir.

Bununla birlikte, widget başına woole sayısı gibi bilgileri tek bir noktaya birleştirmek istense de, bunun her zaman pratik olmadığını not etmek önemlidir. Bazen, yalnızca işler belirli bir boyutta olduğunda işe yarayacak olan mantık kodlaması gerekebilir. Örneğin, eğer her bir woozle bir değere sahipse ve belirli bir widget ile ilişkilendirilen medyanı bulmak isterse, değerleri sıralamak ve orta olanı almak mümkün olabilir ve böyle bir yaklaşım, herhangi bir sayıdaki woolarla çalışabilir, ancak mantık özellikle üç maddenin ortancasını bulmak için elle yazılmış olan, önemli ölçüde daha hızlı olabilirdi.

Bir WOOZLES_PER_WIDGET sabitine sahip olmak, kodu daha okunaklı hale getirebilirken, program mantığında başka ayarlamalar yapmadan değerinin değiştirilemeyeceğini açıkça belirtmek için yorum yapılmalıdır. Bu durumda, üç öğe için kodlanmış mantık ve WOOZLES_PER_WIDGET sabiti hem "her bir parçanın üç çarkı vardır" bilgisini kopyalardı, ancak bu çoğaltmanın faydaları (daha yüksek yürütme hızı) maliyete ağır basabilirdi.


0

Aslında diğer posterler ile aynı fikirdeyim, ancak bunların hepsi uygulanabilirlik, vs.

Tartışmaya küçük bir muhalif ses eklemek istiyorum.

  • Programcılar için sadece önemli. Maaşınızı ödeyen insanlar, yazılım UAT'yi geçtiği sürece daha az umursayamazlardı.
  • Önemi, doğru gereklilikleri almak, proje sponsorlarını dinlemek ve zamanında teslim etmek gibi öğelerin altındadır.

Bu site "Programcılar" için olduğu gibi, sorunun "programcılar bakış açısına" yönelik olduğunu söylemenin güvenli olduğunu düşünüyorum. Ücretli mükellefler, UAT ve önem derecesine ilişkin ifadeleriniz elbette geçerlidir ancak bu soru ile ilgili değildir.
ozz

1
Ben kesinlikle katılmıyorum. İyi yönetim, ilkeleri ve ayrıntılı olarak açıklandığı takdirde neden yapıldığını anlayacaktır. Bu derinlemesine ciddi bir konuşma olmalı, 5 dakikalık bir düşüşle değil.
Michael Durrant,

2
İkinci kurşun noktanız tamamen doğru.
Jim G.

1
@Ozz, mesleğinizin gururu iyi bir programcı için bile önemlidir, ancak belki de "programcılar bakış açısı", "müşteri memnuniyeti" için bir kaygı uyandırması içermelidir.
James Anderson

0

<tl;dr>

Tekrarlanan tüm cevapları okuyamadım, bu yüzden bir şeyi kaçırmış olabilirim (ve kendim de tekrarlayacağım <= burada ne yaptığımı gördün mü?).

Kod çoğaltmasını önlemeyle ilgili harika şeylerin listesi!

  1. Test etmesi kolay: Kodun yalnızca bir kopyasını test etmeniz gerekir.
  2. Düzeltmesi daha kolay: hatayı yalnızca kodun bir 'kopyasında' bulup düzeltmeniz yeterlidir.
  3. Güncellemesi daha kolay (yukarıdakilerle aynı): gerekli değişiklikler, kodun doğru şekilde yeniden kullanılması için zaman ayırdığınız ve aynı satırları kaynaktaki yüzlerce veya binlerce farklı yere kopyalamadığınız için kodları çok az yerde değiştirerek sık sık işlenebilir.
  4. Yeniden kullanımı daha kolay: (birkaç yerde çoğaltılmaz) ve genel olarak adlandırılmış yöntemlerde tutulursa, bunları bulmak ve kendi yazmak yerine kullanmak kolaydır.
  5. Okunması daha kolay: çoğaltılmış kodu okumak zor, çünkü gereksiz yere ayrıntılı; mantığın ve belirli amaçlanan işlevselliğin bir parçası olmayan birçok satır içeriyor (örneğin, eylemin gerçekleşmesi için bir aşama oluşturmak için kullanılan genel komutlar veya birçok yerde gerekli olan genel basit tekrarlanan görevler). Temiz kod, mantığı ve işlevselliği açılır hale getirir, çünkü kod alanını boşaltan hiçbir tekrar yoktur.
  6. (1) ve (5) nedeniyle hata ayıklaması daha kolaydır.
  7. Size zaman ve para kazandırır ve gelecekte daha eğlenceli şeyler yapın; özellikle daha iyi ve sağlam kodlar oluşturun. Bu, sonuç olarak ve yukarıdakilerin hemen hemen hepsinin bir özetidir. Birçok insan aynı işlevi kullanırsa, doFoo1(a, b)can sıkıcı hatalarının ve son durumlarının birçoğunun ortaya çıkması ve çözülmesi olasılığı daha yüksektir. Herkes kodu kopyalayıp yaratırsa doFoo2(specialA)... doFuu2^n(a, b, c)o zaman sorunları çoğalttı doFoo1ve somut bir şekilde çok daha fazla iş yarattı.

</tl;dr>

Uzun versiyon:

Kod çoğaltmayla ilgili sorun, "katlanarak büyümesi" (başka bir deyişle, hızlı bir şekilde genişlemesidir); çünkü, kodu çoğalttığınızda, başkalarına bilmeden başkalarına izin verme yetkisi verdiğinizden (biri için, artık onları yargılamayacaksınız) ve aynı şeyi yapmalarını teşvik edersiniz. Ayrıca yapmamanızı da zorlaştırırsınız, çünkü kaynakta kafa karıştırıcı çok fazla tekrarlama olduğunda, yararlı kodu bulmak ve yeniden kullanmak daha zordur. Özellikle, kod zaten uygun bir şekilde adlandırılmış bir işleve çıkarılmazsa. Bu nedenle, sorunu çözmek için basit bir basit sorunla karşılaşırsanız, muhtemelen sorunu çözen bir kod parçası yazacaksınız… Muhtemelen daha fazla buggy denenmemiş kod ekleyerek birkaç uç durumu kontrol edemezsiniz.

Başka bir şey, bir acemiye göre bu, yalnızca büyük şirketleri etkileyecek bir sorun gibi görünebilir, ancak küçük girişimleri kötü bir şekilde etkilediğini gördüm (10,000 satırlık kopyalanmış sunucu tarafı kodunda olduğu gibi). Bu bir akıl halidir. Sadece DRY'de ustalaşmamalı, diğerlerini de aynı şeyi yapmaya teşvik etmeli; çünkü aksi halde çoğunlukla kodu çoğaltmaya mahkum olacaksınız. DRY araçları el altında ve zorla kullanıldığında bunları uygulamak çok daha kolaydır. Çoğaltılmış kod çok olduğunda, kopyala yapıştır çözümlerinin uygulanması çok daha kolaydır.

Kod çoğaltmasında zararlı bulduğum şeyler:

  1. Bu işlev kullanılabilir mi? Diyelim ki, ihtiyacınız olan (veya ihtiyacınız olan şeyi yapıyor gibi) bir işlev bulduğunuzu, doğru çalışıp çalışmadığını veya çoğaltılıp bırakılmış bir kod olup olmadığını nasıl bileceksiniz?
  2. Yedek kod Bazen insanlar kodu kopyalar, kullanır ve unuturlar (gelecekte her zaman yeniden kopyalayabilirler). Bir noktada birileri, bazı yerlerdeki çoğaltılmış işlevine yapılan çağrıları yeniden düzenleme amacıyla kaldırır, ancak kullanılmayan işlev, aktif olarak kullanılmasa bile kalır.
  3. Aradığınızı bulmak zor. Çoğaltılmış kod yer kaplar ve faydalı ve ihtiyaç duyulan şeyleri (grep gibi araçları kullanarak) bulmayı sadece bir avuç elde etmeniz gereken düzinelerce veya binlerce sonuç elde ettiğinizden daha zor bir görev haline getirir.
  4. (Daha önce de belirtilmiştir): Bakımı zor ve aynı zamanda bakım ve regresyon amacıyla kullanmak zor. Test kodu çoğaltılırsa ve işlevlere uygun şekilde ayıklanmazsa, diğerleri kodu çoğaltır. Herkes QoL'yi daha iyi hale getirmek için kullanımı kolay, okuması kolay bir API yazmakla uğraşacak mı? Tecrübelerime göre hayır, çoğu zaman insanların elinden çıkana kadar daha fazla baskı maddesi olduğunu düşündüğü bir şey vardır.
  5. Kod çoğaltmanın okunması daha zordur, çünkü kodu olması gerekmeyen yerde, ayrıntı vermenin amaçlanan işlevsellik hakkında bilgi eklemediği yerlerde olması gerekir: örneğin, [tekrar tekrar] için kullanılan genel yöntem çağrıları amaçlanan işlevsellik türü için zemin ayarlamak, bu gerçek işlevselliğin ortaya çıkmasını zorlaştırır.
  6. Bu çok söz edildi. Kod yanlışsa, bazı zavallı adam veya adam bu kodun her kullanımını aramalı ve değiştirmelidir. Örneğin, bir kişi, gerektiğinde organize bir Sınıfta çok az yerde mysql_query'ye SQL enjeksiyon güvensiz bir çağrı kullandıysa, bunun yerine PHP PDO'yu kullanmak yerine, düzeltmesi ve PHP PDO'yu kullanması kolay olurdu, ancak çağrıyı kopyalayan bini aşkın yerde kullanıyorlarsa ve bunun üzerine, düzeltmenin pratik olarak dış kaynaklı olması veya bazen daha tehlikeli olması gerekecektir, kodun sıfırdan baştan yazılması gerekecektir.
  7. Çoğaltma kodu kötü bir alışkanlıktır. Bir şeyi pratik yaparsanız, yavaş yavaş ikinci bir doğa haline gelir ve çevrenizdeki insanları etkiler. Junior Devs, sizin yaptığınızı ve ayrıca yaptığınızı da görüyor. Vaaz ettiğiniz şeyi pratik etmeli ve doğru olanı yapmayı alışkanlık haline getirmelisiniz. Daha fazlasını öğren. Yinelenmemiş kod yazmak daha zor ve daha zordur. Bu ödüllendirici bir alışkanlıktır.

Overzealous kod çoğaltma önleme ve işleri özetleme hakkında son notlar:

Bu daha önce de söylenmiştir, ancak bazen kopyadan kaçınmak, "geriye doğru eğilmenize" ve başkalarının anlayamayacağı kadar karmaşık (veya önemsiz) şeyler yapmanıza neden olur. Okunamayan kod yazma (veya şaka olarak “işi koruyan” kod dediğimiz şekilde) kod çoğaltmanın engellenmediği durumlarda bile başlı başına bir sorundur. Bununla birlikte, eğer doğru altyapı ve en iyi uygulamalar baştan başlatılırsa, kod çoğaltmanın önlenmesinin çok daha kolay olduğunu ve insanların çoğu zaman sezgisel olmayan şeyler yapmaktan kaçınabileceğini, böylece kod çoğaltmasının önlenmesi için yapılan gereksiz ve okunamayan iş yığınlarının gelmesini önleyebileceğini öğrendim. o başlangıçtan itibaren bir şey yaparsın.

Ne doğru şeyler yapıyor? Bu, cevaplanması zor bir soru ama bir şey, proje için hangi yöntemlerin gerekli olduğunu tanımlamak ve başkaları tarafından şirket içinde (dışarıda ve dışında) ne uyguladığını görmek ve mümkün olduğunda tekrar kullanmak; Yaptığınız her şeyi kod tabanına belgelemek ve olması gerekenden daha genel bir değerde olmaya çalışıyorum ama o kadar. Sadece tasarım kodunu gereğinden fazla kodun esnek olması için aşırıya kaçmayın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.