it-swarm.asia

DRY ve KISS ilkeleri uyumsuzsa) neleri dikkate almalıyım?

KURU ilkesi bazen programcıları karmaşık, bakımı zor işlevler/sınıflar yazmaya zorlar. Bunun gibi kodlar zaman içinde daha karmaşık ve bakımı zorlaşmaya eğilimlidir. KISS prensibi ihlali.

Örneğin, birden fazla fonksiyonun benzer bir şey yapması gerektiğinde. Her zamanki DRY çözümü, kullanımdaki küçük değişikliklere izin vermek için farklı parametreler alan bir işlev yazmaktır.

Ters açıktır, DRY = değişiklik yapmak için tek bir yer vb.).

Dezavantajı ve ihlal etmesinin nedeni KISS, bunun gibi işlevlerin zaman içinde giderek daha fazla parametre ile gittikçe daha karmaşık olma eğilimi göstermesi, sonuçta programcıların bu tür işlevlerde herhangi bir değişiklik yaparsanız, işlevin diğer kullanım durumlarında hatalara neden olurlar.

Şahsen ben DRY ilkesini takip etmenin KISS ilkesini takip etmesinin mantıklı olduğunu düşünüyorum.

Bir süper karmaşık fonksiyona sahip olmaktan çok benzer 10 süper basit fonksiyona sahip olmayı tercih ederim.

Bir yerde çok korkutucu/zor bir değişiklik yapmaktan ziyade sıkıcı, ama kolay bir şey yapmayı tercih ederim (10 yerde aynı değişikliği veya benzer değişikliği yapın).

Açıkçası ideal yol, KURU ihlal etmeden mümkün olduğunca KISS) yapmaktır. Ancak bazen imkansız gibi görünmektedir.

Ortaya çıkan bir soru "bu kod ne sıklıkta değişiyor?" sık sık değişirse, KURU yapmak daha alakalı olur. Katılmıyorum, çünkü bu karmaşık DRY işlevini değiştirmek genellikle karmaşıklıkta büyümesini ve zamanla daha da kötüleşmesini sağlayacaktır.

Temel olarak, sanırım, genel olarak, KISS> KURU.

Ne düşünüyorsun? Hangi durumlarda DRY her zaman KISS'i kazanmalı ve tam tersi?) Sizce karar verirken neleri düşünüyorsunuz?

71
user158443

KISS özneldir. DRY uygulamak çok kolaydır. Her ikisinin de arkasında iyi fikirler vardır, ancak her ikisinin de kötüye kullanımı kolaydır.

KISS gerçekten ekibinizin gözünde. Ne olduğunu bilmiyorsunuz KISS. Ekibiniz yapıyor. Onlara çalışmanızı gösterin ve basit olduğunu düşünüp düşünmediklerini görün. Bunun kötü bir yargıçsınız çünkü zaten nasıl çalıştığını biliyorsunuz. Kodunuzun başkalarının okuması için ne kadar zor olduğunu öğrenin.

DRY, kodunuzun nasıl göründüğü ile ilgili değildir. Aynı kodu arayarak real DRY sorunlarını tespit edemezsiniz. Gerçek bir DRY sorunu, aynı sorunu tamamen farklı bir görünümle çözüyor olabilirsiniz) Farklı bir yerde farklı bir sorunu çözmek için aynı kodu kullandığınızda DRY) ihlal etmiyorsunuz.Neden? Farklı sorunlar bağımsız olarak değişebilir. ve diğeri değil.

Tasarım kararlarını tek bir yerde alın. Karar vermeyin. Ama şimdi aynı görünmek için olan her kararı aynı yere katlamayın. İkisi de 1 olarak ayarlanmış olsa bile, hem x hem de y'ye sahip olmak iyidir.

Bu bakış açısıyla hiçbir zaman KISS veya DRY) diğerinin üzerine koymuyorum. Aralarında neredeyse gerginlik görmüyorum. Bunların ikisi de önemli ilkelerdir, ancak ikisi de gümüş kurşun değildir.

144
candied_orange

Bu konuda zaten bir yorum to başka bir cevap ile benzer bir sor için candied_orange yazdım ve ayrıca bir farklı cevap içinde biraz dokundu, ancak tekrar ediyor:

DRY, kitapta bulunan bir anımsatıcı "Kendinizi Tekrarlamayın" için şirin üç harfli bir kısaltmadır Pragmatik Programcı , olduğu yerde tümü 8.5) sayfa bölümü . Ayrıca wiki hakkında çok sayfalı açıklama ve tartışma vardır.

Kitaptaki tanım şudur:

Her bilgi parçasının bir sistem içinde tek, açık, yetkili bir temsili olmalıdır.

Çoğaltmanın kaldırılmasıyla ilgili not olduğuna dikkat edin. Yaklaşık tanımlamak kopyalardan hangisi kanonik olan. Örneğin, bir önbelleğiniz varsa, önbellek başka bir şeyin kopyası olan değerleri içerir. Ancak, önbelleğin değil kurallı kaynak olduğu açıkça belirtilmelidir.

İlke değil üç harf KURU. Kitaptaki ve wiki'deki 20 kadar sayfa.

Bu ilke aynı zamanda "Bir Kez Ve Bir Kez" için çok sevimli olmayan dört harfli bir kısaltma olan OAOO ile yakından ilgilidir, bu da eXtreme Programlama'da bir çok sayfalı açıklama ve tartışma wiki .

OAOO wiki sayfasının Ron Jeffries'den çok ilginç bir alıntı var:

Bir keresinde Beck neredeyse tamamen farklı kod iki yama "çoğaltma" olarak ilan gördüm, onlar çoğaltma WERE böylece onları değiştirmek ve daha sonra açıkça daha iyi bir şey bulmak için yeni eklenen çoğaltma kaldırmak.

Hangi konulara değiniyor:

Bir keresinde Beck'in oldukça farklı olan iki döngüye baktığını hatırlıyorum: yapıları ve farklı içerikleri farklıydı, bu da "for" kelimesi dışında çoğaltılmış hiçbir şey değil ve aynı şekilde - farklı şekilde - döngü yapmaları gerçeği Toplamak.

İkinci döngüyü, ilk döngüyle aynı döngüye çevirdi. Bu, önceki sürümün yalnızca koleksiyonun önünü yaptığı için, öğenin koleksiyonun sonuna doğru atlanması için döngü gövdesinin değiştirilmesini gerektiriyordu. Şimdi for ifadeleri aynıydı. "Peki, bu çoğaltmayı ortadan kaldırmak lazım, dedi ve ikinci gövdeyi ilk döngüye taşıdı ve ikinci döngüyü tamamen sildi.

Şimdi bir döngüde iki tür benzer işleme devam ediyordu. Orada bir çeşit kopya buldu, bir yöntem çıkardı, birkaç şey daha yaptı ve voila! kod çok daha iyiydi.

Bu ilk adım - kopya oluşturma - şaşırtıcıydı.

Bu gösterir: yinelenen kod olmadan çoğaltma olabilir!

Ve kitap madalyonun ters yüzünü gösteriyor:

Çevrimiçi şarap siparişi uygulamanızın bir parçası olarak, sipariş ettikleri miktarla birlikte kullanıcınızın yaşını yakalar ve doğrularsınız. Site sahibine göre, ikisi de sayı olmalı ve ikisi de sıfırdan büyük olmalıdır. Böylece doğrulamaları kodlarsınız:

def validate_age(value):
 validate_type(value, :integer)
 validate_min_integer(value, 0)

def validate_quantity(value):
 validate_type(value, :integer)
 validate_min_integer(value, 0)

Kod incelemesi sırasında, yerleşik uzmanlar bu kodu zıplayarak bir DRY ihlali olduğunu iddia eder: her iki işlev gövdesi de aynıdır).

Onlar yanlış. Kod aynıdır, ancak temsil ettikleri bilgi farklıdır. İki işlev, aynı kurallara sahip olan iki ayrı şeyi doğrular. Bu bir tesadüf, bir kopya değil.

Bu, çoğaltılmış koddur, bilginin çoğaltılması değildir.

Çoğaltma hakkında programlama dillerinin doğası hakkında derin bir kavrayışa yol açan büyük bir fıkra vardır: birçok programcı programlama dilini bilir Şema ve bunun LISP ailesinde ilk önce- sınıf ve üst düzey prosedürler, sözcüksel kapsam belirleme, sözcüksel kapanışlar ve tamamen işlevsel, referans olarak şeffaf kod ve veri yapılarına odaklanma. Bununla birlikte, pek çok insanın bilmediği şey, Nesne Odaklı Programlama ve Aktör Sistemlerini (Şema yazarlarının aynı şey olmasa da yakından ilişkili olduğu düşünülen) incelemek için yaratıldığıdır.

Şemadaki temel yordamlardan ikisi, bir yordam oluşturan lambda ve bir yordamı yürüten apply şeklindedir. Şema yaratıcıları iki tane daha ekledi: alpha, bu da a bir ctor (veya nesne) oluşturur ve send bir aktöre (veya nesneye) mesaj gönderir.

Hem apply hem de send olmasının can sıkıcı bir sonucu, prosedür çağrıları için zarif sözdiziminin artık çalışmadığıydı. Şema'da bugün bildiğimiz gibi (ve hemen hemen her LISP'de) basit bir liste genellikle "listenin ilk öğesini bir yordam olarak yorumlayın ve apply listenin geri kalanına yorumlayın, yorumlayın argüman olarak ". Böylece, yazabilirsiniz

(+ 2 3)

ve bu eşdeğer

(apply '+ '(2 3))

(Ya da yakın bir şey, Programım oldukça paslı.)

Ancak, bu artık çalışmaz, çünkü apply veya send (Scheme'nin yaratıcılarının yapmadığı ikisinden birine öncelik vermek istemediğinizi varsayarak) her iki paradigmanın da eşit olmasını istediler). … Yoksa, değil mi? Scheme'nin yaratıcıları, aslında, sembol tarafından başvurulan nesnenin türünü kontrol etmeleri gerektiğini fark ettiler: if + bir prosedürdür, apply it, eğer + bir aktör, send ona bir mesaj. Aslında ayrı apply ve send'ye ihtiyacınız yok, apply-or-send.

Ve bunu yaptılar: apply ve send iki prosedürün kodunu aldılar ve onları bir koşulun iki dalı gibi aynı prosedüre koydular.

Kısa bir süre sonra, o noktaya kadar bir kayıt makinesi için çok düşük seviyeli bir kayıt transferi Meclisi dilinde yazılan Şema yorumlayıcısını da yüksek seviyeli Şemada yeniden yazdılar. Ve şaşırtıcı bir şey fark ettiler: koşullu iki daldaki kod özdeş oldu. Bunu daha önce fark etmemişlerdi: iki prosedür farklı zamanlarda yazılmıştır ("minimum LISP" ile başlamışlar ve sonra OO) ve ayrıntı düzeyini ve düşük düzeyliliği eklediler. Meclisin aslında oldukça farklı yazılmış olmaları anlamına geliyordu, ancak bunları üst düzey bir dilde yeniden yazdıktan sonra, aynı şeyi yaptıkları anlaşıldı.

Bu, Aktörler ve OO hakkında derin bir anlayışa yol açar: nesne yönelimli bir program yürütmek ve sözcüksel kapanışlar ve uygun kuyruk çağrıları ile prosedürel bir dilde bir program yürütmek, aynı şeydir. Tek fark, dilinizin ilkellerinin nesne/aktör veya prosedür olup olmadığıdır. Ama operasyonel olarak, aynı.

Bu aynı zamanda maalesef bugün bile iyi anlaşılmayan bir başka önemli gerçeğe daha yol açıyor: uygun kuyruk çağrıları olmadan nesne yönelimli soyutlamayı koruyamazsınız veya daha agresif bir şekilde koyamazsınız: nesne yönelimli olduğunu iddia eden, ancak uygun kuyruk çağrılarına sahip olmayan bir dil , değil nesne yönelimli. (Ne yazık ki, bu tüm favori dillerim için geçerlidir ve akademik değildir: I have bir yığın taşmasını önlemek için kapsüllemeyi kırmak zorunda kaldım.

Bu çok iyi gizli çoğaltmanın aslında gizlenmiş önemli bir bilgi parçası olduğu ve keşfetme bu çoğaltmanın da bilgiyi ortaya çıkardığı bir örnektir.

39
Jörg W Mittag

Şüphe duyduğunuzda, her zaman sorunu çözen mümkün olan en basit çözümü seçin.

Basit çözüm çok basit olduğu ortaya çıkarsa, kolayca değiştirilebilir. Öte yandan aşırı karmaşık bir çözümün değiştirilmesi de daha zordur ve risklidir.

KISS gerçekten tüm tasarım ilkelerinin en önemlisidir, ancak çoğu zaman göz ardı edilir, çünkü geliştirici kültürümüz zeki ve süslü teknikler kullanmaya çok değer verir. Ancak bazen if gerçekten bir strateji modeli 'den daha iyidir.

DRY ilkesi bazen programcıları karmaşık, bakımı zor işlevler/sınıflar yazmaya zorlar.

Orada dur! DRY ilkesinin amacı daha sürdürülebilir kod elde etmektir. Belirli bir durumda ilkeyi uygulamak, daha az bakılabilir koda, bu durumda prensip uygulanmamalıdır.

Bu ilkelerin hiçbirinin kendi başlarına hedef olmadığını unutmayın. hedefi amacını yerine getiren ve gerektiğinde uyarlanabilen ve genişletilebilen yazılımlar yapmaktır. Hem KISS, DRY, SOLID hem de diğer tüm prensipler bu hedefe ulaşmak için anlamına gelir. Ancak hepsinin sınırlamaları vardır ve nihai hedefe karşı çalışan bir şekilde uygulanabilir, bu da çalışma ve bakım yapılabilir yazılım yazmaktır.

8
JacquesB

IMHO: KISS/DRY koduna odaklanmayı bırakır ve kodu yönlendiren gereksinimlere odaklanmaya başlarsanız, aradığınız daha iyi cevabı bulacaksınız.

İnanıyorum:

  1. Birbirimizi pragmatik kalmaya teşvik etmeliyiz (yaptığınız gibi)

  2. Testin önemini tanıtmayı asla bırakmamalıyız

  3. Gereksinimlere daha fazla odaklanmak sorularınızı çözecektir.

TLDR

Gereksiniminiz parçaların bağımsız olarak değişmesini sağlamaksa, yardımcı fonksiyonlara sahip olmadan fonksiyonları bağımsız tutun. Gereksiniminiz (ve gelecekte yapılacak değişiklikler) tüm işlevler için aynıysa, bu mantığı yardımcı bir işleve taşıyın.

Bence şimdiye kadarki tüm cevaplarımız bir Venn diyagramı oluşturuyor: hepimiz aynı şeyi söylüyoruz, ama farklı bölümlere detaylar veriyoruz.

Ayrıca, hiç kimse testten bahsetmedi, bu yüzden bu cevabı yazdım. Birisi programcılar değişiklik yapmaktan korkuyorsa, değil test hakkında konuşmak çok akılsız olduğunu düşünüyorum! Sorun kodla ilgili "düşünürsek" bile, asıl sorun test eksikliğidir. İnsanlar önce otomatik teste yatırım yaptığında, nesnel olarak üstün kararlar daha gerçekçi hale gelir.

İlk olarak, korkudan kaçınmak bilgeliktir - İyi İş!

İşte söylediğiniz bir cümle: programcılar bu tür [yardımcı] işlevlerde herhangi bir değişiklik yapmaktan çok korkarlar veya işlevin diğer kullanım durumlarında hatalara neden olurlar

Bu korkunun düşman olduğunu kabul ediyorum ve sadece basamaklı böcek/iş/değişiklik korkusuna neden oluyorsa asla ilkelere bağlı kalmalısınız. Birden fazla işlev arasında kopyalama/yapıştırma, bu korkuyu kaldırmanın sadece yoluysa (ki buna inanmıyorum - aşağıya bakın), o zaman yapmanız gereken budur.

Bu değişiklik yapma korkusunu hissettiğiniz ve bu konuda bir şeyler yapmaya çalıştığınız gerçeği, kodu geliştirmek için yeterince umursamayan diğerlerinden daha iyi bir profesyonel olmanızı sağlar - sadece söyledikleri şeyi yaparlar ve biletlerini kapatmak için minimum değişiklikleri yapın.

Ayrıca (ve zaten bildiğinizi tekrarladığımı söyleyebilirim): insanların becerileri koz tasarım becerileri. Şirketinizdeki gerçek insanlar tamamen kötüyse, "teorinizin" daha iyi olması önemli değildir. Nesnel olarak daha kötü kararlar vermeniz gerekebilir, ancak bunu sürdürecek kişilerin anlayabileceği ve onlarla çalışabileceğini biliyorsunuz. Ayrıca, birçoğumuz kimin (IMO) mikro yönetimi yönettiğini ve ihtiyaç duyulan yeniden düzenlemeyi her zaman reddetmenin yollarını da buluyoruz.

Müşteriler için kod yazan bir satıcı olan biri olarak, bunu her zaman düşünmeliyim. Currying ve meta-programlamayı kullanmak isteyebilirim çünkü objektif olarak daha iyi olduğu iddiası var, ama gerçek hayatta insanların bu kodla karıştırıldığını görüyorum çünkü bu görsel olarak açık neler değil.

İkincisi, Daha İyi Testler Aynı Anda Birden Fazla Sorunu Çözer

Etkili, kararlı, zaman kanıtlanmış otomatik testlere (birim ve/veya entegrasyon) sahipseniz (ve sadece), o zaman bahse girerim korkunun kaybolduğunu göreceksiniz. Otomatik testlere yeni başlayanlar için, otomatik testlere güvenmek çok korkutucu olabilir; Yeni gelenler tüm bu yeşil noktaları görebilir ve bu yeşil noktaların gerçek hayattaki üretimin çalışmasını yansıttığına çok az güvenebilirler. Bununla birlikte, kişisel olarak, otomatik testlere güveniyorsanız, o zaman duygusal/ilişkisel olarak başkalarını da güvenmeye teşvik edebilirsiniz.

Sizin için (henüz yapmadıysanız) ilk adım, yapmadıysanız test uygulamalarını araştırmaktır. Dürüst olmak gerekirse, bu şeyleri zaten bildiğinizi varsayıyorum, ancak orijinal yayında bu sözü görmediğim için, bunun hakkında konuşmak zorundayım. Çünkü otomatik testler are bu önemli ve durumunuzla alakalı.

Tüm test uygulamalarını burada tek bir gönderide tek başına kaynatmaya çalışmayacağım, ancak "refactor proof" testleri fikrine odaklanmanız için size meydan okuyacağım. Kodlama için bir birim/entegrasyon testi yapmadan önce, kendinize az önce yazdığınız testi kıracak olan CUT'u (test edilen kod) yeniden düzenlemenin geçerli bir yolu olup olmadığını sorun. Bu doğruysa, (IMO) testi silin. Refactor olduğunuzda gereksiz yere kırılmayan daha az otomatik teste sahip olmak daha iyidir, çünkü yüksek test kapsamına sahip olduğunuza (miktar üzerinden kalite) bir şey söylemektir. Sonuçta, daha kolay yeniden düzenleme, otomatik testlerin ana amacıdır (IMO).

Bu "refactor-proof" felsefesini zaman içinde benimsediğim için şu sonuçlara vardım:

  1. Otomatik entegrasyon testleri, birim testlerden daha iyidir
  2. Entegrasyon testleri için, gerekiyorsa, "sözleşme testleri" ile "simülatörler/sahte" yazın
  3. Özel bir API'yi asla test etmeyin - özel sınıf yöntemleri veya dosyadan dışa aktarılmamış işlevler olsun.

Referanslar:

Test uygulamalarını araştırırken, bu testleri kendiniz yazmak için fazladan zaman ayırmanız gerekebilir. Bazen en iyi yaklaşım bunu kimseye yaptığınızı söylememektir, çünkü sizi mikro yönetirler. Açıkçası Bu her zaman mümkün değildir çünkü test etme ihtiyacı, iyi bir iş/yaşam dengesi ihtiyacından daha büyük olabilir. Ancak, bazen gerekli olan testleri/kodu yazmak için bir görevi bir veya iki gün gizlice erteleyebileceğiniz kadar küçük şeyler vardır. Bu, biliyorum, tartışmalı bir ifade olabilir, ama bence bu gerçek.

Ayrıca, başkalarını, testleri kendileri anlama/yazma yolunda adımlar atmaya teşvik etmek için mümkün olduğunca politik olarak ihtiyatlı olabilirsiniz. Belki de kod incelemeleri için yeni bir kural getirebilecek teknik lider sizsiniz.

Meslektaşlarınızla test hakkında konuştuğunuzda, umarım yukarıdaki # 1 (pragmatik olun) ilk önce dinlemeye devam etmeyi ve saldırgan olmamayı hatırlatır.

Üçüncü olarak, Kurallara değil Gereksinimlere Odaklanın

Kodumuza çok fazla odaklanıyoruz ve kodumuzun çözmesi gereken daha büyük resmi derinlemesine anlamıyoruz! Bazen kodun temiz olup olmadığını tartışmayı bırakmanız ve kodu kullanması gereken gereksinimleri iyi anladığınızdan emin olmanız gerekir.

Right şeyi yapmanız KISS/DRY gibi fikirlere göre kodunuzun "güzel" olduğunu hissetmenizden daha önemlidir. Bu yüzden bu yakalama ifadelerini önemsemekte tereddüt ediyorum, çünkü (pratikte) yanlışlıkla gereksinimler'in iyi kod kalitesi hakkında iyi bir karar verdiklerini düşünmeden kodunuza odaklanmanızı sağlarlar. .


İki işlevin gereksinimleri birbirine bağlı/aynı ise, bu gereksinimin uygulama mantığını bir yardımcı işleve yerleştirin. Bu yardımcı işlevin girdileri, bu gereksinim için iş mantığının girdileri olacaktır.

İşlevlerin gereksinimleri farklıysa, bunlar arasında kopyalayın/yapıştırın. Her ikisi de bu anda aynı koda sahip olurlarsa, ancak olabilir bağımsız olarak doğru bir şekilde değişirse, yardımcı fonksiyon kötü olur, çünkü gereksinim olan başka bir işlevi etkiler bağımsız olarak değişmek.

Örnek 1: "getReportForCustomerX" ve "getReportForCustomerY" adlı bir işleve sahipsiniz ve ikisi de veritabanını aynı şekilde sorgular. Ayrıca, her müşterinin raporlarını tam anlamıyla istedikleri şekilde özelleştirebileceği bir iş gereksinimi olduğunu varsayalım. Bu durumda, tasarım gereği, müşteriler raporlarında farklı sayılar ister. Dolayısıyla, rapora ihtiyaç duyan yeni bir Z müşteriniz varsa, sorguyu başka bir müşteriden kopyalayıp yapıştırmak ve daha sonra kodu işlemek ve bir tane taşımak en iyisi olabilir. Sorgular tam olarak aynı olsa bile, bu işlevlerin tanımlayıcı noktası bir müşteriden diğerini etkileyen ayrı değişikliktir. Tüm müşterilerin raporlarında isteyecekleri yeni bir özellik sağladığınız durumlarda, evet: muhtemelen tüm işlevler arasında aynı değişiklikleri yazacaksınız.

Bununla birlikte, devam edip queryData adlı bir yardımcı işlev yapmaya karar verdiğimizi varsayalım. Bunun kötü olmasının nedeni, bir yardımcı işlev tanıtarak daha fazla basamaklı değişiklik olmasıdır. Sorgunuzda tüm müşteriler için aynı olan bir "where" cümlesi varsa, bir müşteri onlar için bir alanın farklı olmasını istediği anda, 1 yerine X işlevi içindeki sorguyu değiştirmek için, 1 ) müşteri X'in istediği şeyi yapmak için sorguyu değiştirin 2) başkaları için bunu yapmamak için sorguya koşull ekleyin. Bir sorguya daha fazla koşul eklemek mantıksal olarak farklıdır. Ben bir sorguya bir alt cümle eklemek biliyor olabilir, ama bu ben kullanmayanlar için performansı etkilemeden bu alt cümle koşullu yapmak nasıl biliyorum anlamına gelmez.

Böylece, bir yardımcı işlev kullanmanın bir yerine iki değişiklik gerektirdiğini fark edersiniz. Bunun tartışmalı bir örnek olduğunu biliyorum, ama benim için Boole karmaşıklığı benim deneyimime göre doğrusal olarak daha fazla büyüyor. Bu nedenle, koşullu ekleme eylemi, insanların her zaman güncellemeleri gereken "bir şey daha" ve "bir şey daha" olarak sayılır.

Bu örnek, bana kulağa geliyor, karşılaştığınız durum gibi olabilir. Bazı insanlar bu işlevler arasında kopyalama/yapıştırma fikrini duygusal olarak kandırırlar ve böyle duygusal bir tepki tamamdır. Ancak "basamaklı değişiklikleri en aza indirme" ilkesi, kopyalama/yapıştırma işleminin ne zaman uygun olduğu konusundaki istisnaları objektif olarak ayırt edecektir.

Örnek 2: Üç farklı müşteriniz var, ancak raporları arasında farklı olmasına izin verdiğiniz tek şey sütunların başlıklarıdır. Bu durumun çok farklı olduğuna dikkat edin. İş gereksinimimiz artık "raporda rekabet esnekliğine izin vererek müşteriye değer sağlamak" değildir. Bunun yerine, iş gereksinimi "müşterilerin raporu çok fazla özelleştirmesine izin vermeyerek fazla işten kaçınmak" tır. Bu durumda, sorgu mantığını değiştireceğiniz tek zaman, her müşterinin aynı değişikliği aldığından emin olmanız gereken zamandır. Bu durumda, kesinlikle bir dizi girdi olarak bir yardımcı işlev oluşturmak istersiniz - sütunlar için "başlıklar" nelerdir.

Gelecekte, ürün sahipleri müşterilerin sorgu hakkında bir şey özelleştirmesine izin vermek istediklerine karar verirse, yardımcı işleve daha fazla bayrak ekleyeceksiniz.

Sonuç

Kod yerine gereksinimlere ne kadar çok odaklanırsanız, kod değişmez gereksinimler için o kadar izomorfik olur. Daha iyi kod yazıyorsunuz doğal olarak.

4
Alexander Bird

Makul bir orta yol bulmaya çalışın. Çok sayıda parametreye ve karmaşık koşullara yayılmış birden fazla işlevin yerine, birkaç basit işleve bölün. Arayanlarda bir miktar tekrar olacaktır, ancak ortak kodu ilk etapta işlevlere taşımamış olmanız kadar değil.

Son zamanlarda Google ve iTunes uygulama mağazalarıyla arayüz oluşturmak için üzerinde çalıştığım bazı kodlarla karşılaştım. Genel akışın çoğu aynıdır, ancak her şeyi kapsüllemek için kolayca bir işlev yazamayacağım kadar farklılıklar vardır.

Yani kod şu şekilde yapılandırılmıştır:

Google::validate_receipt(...)
    f1(...)
    f2(...)
    some google-specific code
    f3(...)

iTunes::validate_receipt(...)
    some iTunes-specific code
    f1(...)
    f2(...)
    more iTunes-specific code
    f3(...)

Her iki doğrulama işlevinde f1 () ve f2 () çağrılmasının DRY prensibini ihlal ettiğinden çok endişelenmiyorum çünkü onları birleştirmek daha karmaşık hale getirecek ve tek, iyi tanımlanmış bir performans sergilemeyecektir. görev.

3
Barmar

Kent Beck, bu soruyla ilgili 4 basit tasarım kuralını benimsedi. Martin Fowler tarafından ifade edildiği gibi:

  • Testleri geçer
  • Niyeti gösterir
  • Çoğaltma yok
  • En az element

Orta ikisinin düzeni hakkında çok fazla tartışma var, bu yüzden onları eşit derecede önemli olarak düşünmeye değer olabilir.

KURU listedeki üçüncü öğedir ve KISS 2. ve 4. kombinasyonların, hatta tüm listenin bir kombinasyonu olarak düşünülebilir.

Bu liste DRY/KISS ikilemine alternatif bir görünüm sağlar. DRY kodunuzun amacı açıklanıyor mu? KISS kodunuz mu?)

Hedef DRY veya KISS, iyi bir kod. DRY, KISS ve bu kurallar oraya ulaşmak için sadece araçlardır.

3
Blaise Pascal