Tasarım desenlerinde neden bu kadar çok sınıfa ihtiyacımız var?


209

Ben yaşlılar arasında küçük geliştiriciyim ve onların düşüncelerini ve akıl yürütmelerini anlama konusunda çok zorlanıyorum.

Domain Driven Design (DDD) okuyorum ve neden bu kadar çok sınıf oluşturmamız gerektiğini anlamıyorum. Bu yazılım tasarım yöntemini takip edersek, en fazla iki dosya ve 3-4 işlevle değiştirilebilen 20-30 sınıfla bitiririz. Evet, bu karışık olabilir, ama çok daha sürdürülebilir ve okunabilir.

Ne zaman bir tür ne yaptığını görmek istediğimde EntityTransformationServiceImpl, birçok sınıfı, ara yüzü, işlev çağrısını, kurucuyu, yaratılışını vb. Takip etmem gerekiyor.

Basit matematik:

  • 60 satır kukla kod vs 10 sınıf X 10 (diyelim ki tamamen farklı bir mantığa sahibiz) = 600 karışıklık kodu satırı - 100 sınıf + biraz daha fazlası bunları sarmak ve yönetmek için; bağımlılık enjeksiyonu eklemeyi unutmayın.
  • 600 satırlık kod okunuyor = bir gün
  • 100 sınıf = bir hafta, hangisinin ne yaptığını hala unutma

Herkes bakımı kolay olduğunu söylüyor, peki ne için? Her yeni işlevsellik eklediğinizde, fabrikalar, varlıklar, hizmetler ve değerler içeren beş sınıf daha eklersiniz. Bu tür bir kodun dağınık koddan daha yavaş hareket ettiğini hissediyorum.

Diyelim ki, bir ay içinde 50K LOC karışık kod yazarsanız, DDD işi çok fazla inceleme ve değişiklik gerektirir (her iki durumda da testleri önemsemiyorum). Daha fazla değilse, basit bir ekleme hafta alabilir.

Bir yılda, çok sayıda karışık kod yazarsınız ve hatta birden çok kez yeniden yazabilirsiniz, ancak DDD stilinde, hala karışık kodla rekabet edebilecek kadar özelliğiniz yoktur.

Lütfen açıkla. Neden bu DDD stiline ve birçok desene ihtiyacımız var?

UPD 1 : Çok büyük cevaplar aldım, lütfen bir yere yorum ekleyebilir veya cevabınızı okuma listesi için bağlantı ile düzenleyebilir misiniz (hangisinden başlayacağınızdan emin değilsiniz, DDD, Tasarım Desenleri, UML, Kod Tamamlandı, Refactoring, Pragmatik,. .. pek çok iyi kitap) tabii ki sıralı olarak, böylece bazılarınız gibi anlamaya başlayabilir ve kıdemli olabilirim.


81
Burada iyi bir soru olduğunu düşünüyorum ama abartı ve hayal kırıklığının ardında saklanıyor. @ user1318496, sorunuzu bir miktar yeniden düzenlemekten faydalanabilirsiniz.
MetaFight,

48
Dilinizi emmek çünkü ayak parmaklarına basma riski altında. Bunu, olduğundan daha fazla kullanmayın: emici bir dil, çeşitli nedenlerden dolayı çoğu zaman doğru teknik seçimdir, ancak bu, onu emersiz kılmaz. Asıl sorunuza gelince, doğruluk okunabilirlikten daha önemlidir. Ya da biraz daha farklı bir ifadeyle: okunabilirlik, doğruluk hakkında muhakeme yapılmasına olanak sağladığı sürece önemlidir. Peki hangisini test etmek daha kolay, 100 sınıfınız mı yoksa monolitik tanrı sınıfınız mı? 100 basit sınıfla bahse giriyorum.
Jared Smith,

87
“Evet, bu dağınık olabilir, ama çok daha bakımı yapılabilir ve okunabilir.”. Dağınıksa nasıl okunabilir ve bakımı yapılabilir?
Polygnome,

37
@Polygnome: Aynı yorumu yazmak üzereydim. Genç geliştiricilerin bir diğer seçenek yorumu ise, "Bu tür bir kodun dağınık koddan çok daha yavaş hareket ettiğini hissediyorum." Zamanınızın yarısını duvarlara sokarak geçirirseniz, olabildiğince hızlı koşmanız iyi olmaz! Yavaş pürüzsüz, pürüzsüz hızlı.
Eric Lippert,

40
Java yapmazsan yapmazsın. Sahip olduğun tek şey Java olduğunda, her şey bir sınıfa benziyor.
Ocaklar

Yanıtlar:


336

Bu bir optimizasyon problemi

İyi bir mühendis, bir optimizasyon probleminin hedef olmadan anlamsız olduğunu bilir. Az önce optimize etmek zorunda optimize olamaz için bir şey. Örneğin, derleyici seçenekleriniz hız için optimizasyon ve kod boyutu için optimizasyon içerir; bunlar bazen zıt hedeflerdir.

Karıma, masamın ekler için optimize edilmiş olduğunu söylemek istiyorum Bu sadece bir yığın ve eşya eklemek çok kolay. Karım almak için optimize edilmiş olsaydı tercih ederdi, yani eşyalarımı biraz organize ettim, böylece bir şeyler bulabildim. Bu elbette eklemeyi zorlaştırıyor.

Yazılım aynı. Ürün yaratımı için kesinlikle optimizasyon yapabilirsiniz - organize etmekten endişe duymadan bir ton monolitik kod oluşturabilirsiniz . Daha önce fark ettiğiniz gibi, bu çok, çok hızlı olabilir. Alternatif, bakım için optimize etmektir - dokunuşu daha zor hale getirir, ancak değişiklikleri daha kolay veya daha az riskli hale getirir. Yapısal kodun amacı budur.

Başarılı bir yazılım ürününün yalnızca bir kez yaratılacağını, ancak birçok kez değiştirileceğini öneririm. Tecrübeli mühendisler, yapılandırılmamış kod tabanlarının kendi yaşamlarını sürdüğünü ve büyük bir risk yaratmadan çok küçük değişiklikler yapmak çok zor olana kadar boyut ve karmaşıklıkta büyüyen ürünler haline geldiğini gördü. Kod yapılandırılmışsa, risk bulunabilir. Bu yüzden bu kadar belaya giriyoruz.

Karmaşıklık, unsurlardan değil ilişkilerden gelir

Analizinizde miktarlara, kod miktarına, sınıf sayısına, vb. Baktığınızı fark ediyorum. Bunlar ilginç olsa da, asıl etki, kombinasyonlar halinde patlayan elementler arasındaki ilişkilerden geliyor. Örneğin, 10 işleviniz varsa ve hangisine bağlı olduğuna dair hiçbir fikriniz yoksa, endişelenmeniz gereken 90 olası ilişkiniz (bağımlılıklar) var - on işlevden her biri diğer dokuz işlevden herhangi birine bağlı olabilir ve 9 x 10 = 90. Hangi fonksiyonların hangi değişkenleri veya verinin nasıl aktarıldığını değiştirdiğini hiçbir fikriniz olmayabilir, bu nedenle kodlayıcıların belirli bir sorunu çözerken endişelenecek bir sürü şeyi olabilir. Buna karşılık, 30 sınıfınız varsa ancak akıllıca düzenlenmişlerse, örneğin bir yığın halinde düzenlenmiş veya yerleştirilmişlerse, en az 29 ilişki kurabilirler.

Bu, ekibinizin verimliliğini nasıl etkiler? Daha az bağımlılık var, sorun çok daha fazla izlenebilir; Kodlayıcılar, bir değişiklik yaptıklarında kafasında zillion bir şeylerle uğraşmak zorunda kalmazlar. Dolayısıyla, bağımlılıkları en aza indirmek, bir problemi ustalıkla yapma yeteneğiniz için büyük bir destek olabilir. Bu yüzden işleri sınıflara veya modüllere bölüp değişkenleri olabildiğince sıkı bir şekilde kapsamalı ve SOLID ilkelerini kullanıyoruz.


103
Bununla birlikte, fazla sayıda sınıf ve dolaysızlığın NOR bakımının anlaşılmasında yardımcı OLMADIĞINI not ederim. Ve kıvrılmış kontrol akışları da (aka, geri arama cehennemi).
Matthieu M.

9
@JohnWu bu açıklama okuduğumdan birisini anlamanın en iyi ve kolay yolu.
Adriano Repetti

13
İyi yazılmış, ancak "bir kez yaratıldı, ancak birçok kez değiştirildi" nin neden önemli olduğu belki de eksik mi? (Tüm kodlar içeriyorsa, düzeltmeden önce her şeyin nasıl çalıştığınıEntityTransformationServiceImpl öğrenmek zorunda kalırsınız - ancak örneğin formatta bir sınıf varsa ve bir sınıf bunu çözüyorsa, sadece bu kısmın nasıl çalıştığını öğrenmeniz gerekir . ~ 3 ay sonra kendi kodunuzu okumak yabancı bir kişinin kodunu okumak gibidir.) Çoğunlukla bunu bilinçli olarak düşündüğümüzü hissediyorum, ama bu deneyim yüzünden olabilir. Bundan% 100 emin değil. Formatter
R. Schmitz

17
Kombinatoryal için tam 10 × 10 = 100'ü seçerdim: bu işlevler özyinelemede açıkça değil, özyinelemeli ve özellikle kötü kodda olabilir.
KRyan

32
"Alternatif, bakım için optimize etmektir - bir dokunuş yaratmayı daha zor hale getirir, ancak değişiklikleri daha kolay veya daha az riskli hale getirir. Yapısal kodun amacı budur." Daha fazla sınıf = daha fazla sürdürülebilirlik olduğu fikrine kapılıyorum. Özellikle, birçok sınıfa saçılma mantığı çoğu zaman kodda genel olarak mantıksal kavramları bulmayı zorlaştırır (özellikle kavramların görünür olmasını sağlamak için çok kasıtlı bir göz olmadan), ki bu da sürdürülebilirliği büyük ölçüde azaltır.
jpmc26

67

Öncelikle, okunabilirlik ve bakım sürdürebilirlik genellikle bakanın gözündedir.

Size okunabilir olan şey komşunuza olmayabilir.

Bakım yapılabilirlik genellikle keşfedilebilirliğe (kod tabanında keşfedilen bir davranış veya kavramın ne kadar kolay olduğu) azalır ve keşfedilebilirlik başka bir öznel şeydir.

DDD

DDD'nin geliştirici ekiplerine yardım etmesinin yollarından biri, kod kavramlarınızı ve davranışlarınızı organize etmenin özel (henüz öznel) yöntemini önermektir. Bu sözleşme bir şeyleri keşfetmeyi ve dolayısıyla uygulamayı sürdürmeyi kolaylaştırır.

  • Etki alanı kavramları, Varlıklar ve Toplamlar olarak kodlanır
  • Etki alanı davranışı Varlıklar veya Etki Alanı Hizmetlerinde bulunur
  • Agrega Kökü Tutarlılığı Sağlanır
  • Kalıcılık endişeleri Depolar tarafından ele alınmaktadır.

Bu düzenlemenin korunması nesnel olarak kolay değildir . Ancak, herkes DDG bağlamında çalıştıklarını anladığı zaman bakımı ölçülebilir bir şekilde kolaydır.

Sınıflar

Sınıflar sürdürülebilirlik, okunabilirlik, keşfedilebilirlik vb. İle yardımcı olur ... çünkü iyi bilinen bir kongredir .

Nesne Yönelimli ayarlarda, Sınıflar tipik olarak yakından ilişkili davranışları gruplamak ve dikkatli bir şekilde kontrol edilmesi gereken durumu kapsüllemek için kullanılır.

Kulağa çok soyut geldiğini biliyorum ama bu şekilde düşünebilirsiniz:

Sınıflar ile, içlerindeki kodun nasıl çalıştığını bilmeniz gerekmez . Sadece bilmeniz gereken şey sınıfı sorumludur.

Sınıflar, iyi tanımlanmış bileşenler arasındaki etkileşimler açısından uygulamanız hakkında düşünmenize olanak sağlar .

Bu, uygulamanızın nasıl çalıştığını düşünürken bilişsel yükü azaltır. 600 satır kodun neyi başardığını hatırlamak yerine, 30 bileşenin nasıl etkileşime girdiğini düşünebilirsiniz .

Ve, bu 30 bileşen muhtemelen uygulamanızın 3 katmanını kapsıyorsa , muhtemelen her biriniz bir seferde yaklaşık 10 bileşen düşünmeniz gerekir.

Bu oldukça yönetilebilir görünüyor.

özet

Temel olarak, kıdemli devlerin yaptıklarını görüyorsunuz:

Uygulamayı sınıflar hakkında akla kolay hale getiriyorlar .

Daha sonra bunları katmanları düşünmesi kolay bir şekilde düzenliyorlar .

Bunu yapıyorlar çünkü uygulama büyüdükçe bir bütün olarak bunun nedeninin zorlaştığını biliyorlar. Katman ve Sınıflara ayırmak, tüm uygulama hakkında hiçbir zaman gerekçeleri olmadığı anlamına gelir. Sadece küçük bir alt kümesini düşünmeleri gerekirdi.


5
Küçük sınıfların yanı sıra değiştirilmesi / refaktörü kolaydır.
Zalomon

12
Overengineering yok değil iddian rağmen oldukça tersini, - daha sürdürülebilir ya anlaşılabilir kodunu verin. AddressServiceRepositoryProxyInjectorResolverSorunu daha zarif bir şekilde çözebildiğiniz zaman kimin ihtiyacı var ? Tasarım desenleri uğruna tasarım kalıpları sadece gereksiz karmaşıklığa ve ayrıntılara neden olur.
vikingsteve

27
Evet, aşırı mühendislik yapmak kötü. Yani yavru öldürüyor. Buradaki hiç kimse ikisini de savunmuyor. logicallyfallacious.com/tools/lp/Bo/LogicalFallacies/169/...
MetaFight

5
Ayrıca, yazılım mühendisliği bağlamında "şıklık" genellikle bir Gelincik Sözüdür. en.wikipedia.org/wiki/Weasel_word
MetaFight

11
Aynı kural düzenleme için herhangi bir yaklaşım söylenebilir. Her şey bakım ekibine bağlı olarak kodun neden bu kadar organize olduğunu anlar. Bu, iyi kurulmuş ve anlaşılmış sözleşmeler kullanmanın esas noktasıdır.
MetaFight

29

Lütfen bana açıkla, neden bu DDD tarzına, bir sürü kalıba ihtiyacımız var?

Birincisi, bir not: DDD'nin önemli kısmı kalıplar değil , geliştirme çabalarının işletme ile uyumlaştırılmasıdır. Greg Young, mavi kitaptaki bölümlerin yanlış sırada olduğunu belirtti .

Fakat sizin özel sorunuza göre: beklediğinizden çok daha fazla sınıf olma eğilimindedir, (a) çünkü alan davranışını sıhhi tesisattan ayırt etmek için çaba harcanır ve (b) çünkü bu kavramları sağlamak için fazladan çaba sarf edilir. etki alanı modelinde açıkça ifade edilir.

Açıkça, etki alanında iki farklı kavramınız varsa, aynı şeyi bellek temsilinde paylaşsalar bile modelde farklı olmalıdırlar .

Aslında, bir etki alanı uzmanının ona bakabilmesi ve hataları tespit edebilmesi için modelinizi işletme dilinde tanımlayan bir alana özgü dil oluşturuyorsunuz.

Ek olarak, endişelerin ayrılmasına biraz daha dikkat edildiğini görürsünüz; ve bazı yeteneklere sahip tüketicileri uygulama detaylarından izole etme nosyonu. Bkz. DL Parnas . Net sınırlar, tüm çözümünüzde titremeden etkiler olmadan uygulamayı değiştirmenizi veya genişletmenizi sağlar.

Buradaki motivasyon: Bir işletmenin temel yetkinliğinin bir parçası olan bir uygulama için (rekabet avantajı elde ettiği bir yer anlamına gelir), bir alan davranışını daha kolay ve ucuz bir şekilde değiştirerek daha iyi bir çeşitliliğe sahip olmak isteyeceksiniz. Aslında, programın hızlı bir şekilde gelişmesini istediğiniz (zaman içinde durumun nasıl geliştiği) ve yavaşça değiştirmek istediğiniz diğer kısımların (durumun nasıl kaydedildiği); Ekstra soyutlama katmanları yanlışlıkla bir diğerine birleşmekten kaçınmaya yardımcı olur.

Adalet: bazıları da Nesneye Yönelik Beyin Hasarıdır. Başlangıçta Evans tarafından açıklanan desenler, 15+ yıl önce katıldığı Java projelerine dayanıyor; durum ve davranış, bu tarz ile sıkı sıkıya bağlantılıdır; bkz . Stuart Halloway tarafından Algılanma ve Eylem veya John Carmack'in İnlining Code .

Hangi dilde çalışıyor olursanız olun, işlevsel bir tarzda programlama size fayda sağlar. Uygun olduğunda ne yapmalı ve ne zaman uygun olmadığı konusunda karar vermeyi düşünmelisiniz. Carmack, 2012


2
Bunu okuyana kadar kendi cevabımı ekleyecektim. İlk paragrafı vurgulamak isterim; amaç, yazılımı iş gereksinimlerine uygun hale getirmek için iş kavramlarını yazılımda modellemektir. Adil olmak gerekirse, projeyi yönlendiren analist, teslimat süresinin ne kadar sürdüğünü de ifade etmeli ve kod / test kalitesi veya tamlığı buna göre ayarlanmalıdır.
Sentinel

1
John Carmack harika bir örnek IMO, çünkü hem temiz hem de anlaşılması kolay ve aynı zamanda iyi bir performans gösteren kod yazması ile tanınıyor. Bu, özellikle ilerleyen teknolojilerle kodunu takip ettiğinizde görülebilir - daha iyi CPU'lar ve belleğe sahip, "bu gerçekten ciddiyetli olması gereken" deyince "bu" gerçekten / açık / yalıtılmış olması gereken ... ". Tanıdığım en pragmatik programcılardan biri :)
Luaan

Bence buradaki en iyi cevap bu. DDD'de hiçbir şekilde satılmadığım halde, bu cevap kesinlikle en azından gerçekten ne olduğunu ve hiçbir şey ifade etmeyen ortak pratiklere başvurmaktan ziyade gerçek bir motivasyonu açıklıyor.
jpmc26

29

Diğer cevaplarda birçok iyi nokta var, ancak yaptığınız önemli bir kavramsal hatayı kaçırdıklarını veya vurgulamadıklarını düşünüyorum:

Tüm programı anlama çabasını karşılaştırıyorsunuz.

Bu, çoğu programda gerçekçi bir iş değildir. Basit programlar bile o kadar çok koddan oluşuyor ki, her şeyi kafanın içinde herhangi bir zamanda yönetmek imkansızdır. Tek şansınız, elinizdeki görevle ilgili bir programı bulmak (bir hatayı düzeltmek, yeni bir özellik uygulamak) ve bununla çalışmak.

Programınız çok büyük fonksiyonlardan / yöntemlerden / sınıflardan oluşuyorsa, bu neredeyse imkansızdır. Bu kod grubunun sorununuzla ilgili olup olmadığına karar vermek için yüzlerce kod satırını anlamanız gerekir. Verdiğiniz tahminlerle, üzerinde çalışmanız gereken kod parçasını bulmak için bir hafta harcamak kolaydır.

Bunu, belirli bir mantık parçasını nerede bulacağınızı / koyacağınızı açıklığa kavuşturan, paketler / ad alanları şeklinde adlandırılmış ve düzenlenmiş küçük işlev / yöntemler / sınıflarla bir kod tabanına karşılaştırın. Pek çok durumda, probleminizi çözmek için doğru yere doğru atlayabilirsiniz ya da en azından hata ayıklayıcınızı ateşlemenizin bir kaç şerbetle sizi doğru noktaya getireceği bir yere atlayabilirsiniz.

Her iki sistemde de çalıştım. Fark, karşılaştırılabilir işler ve karşılaştırılabilir sistem boyutu için performanstaki iki büyüklük derecesi kolayca olabilir.

Bunun diğer faaliyetler üzerindeki etkisi:

  • Küçük ünitelerle test yapmak çok daha kolay
  • daha az birleştirme çatışması çünkü iki geliştiricinin aynı kod parçasında çalışma şansı daha küçük.
  • daha az çoğaltma, çünkü parçaları yeniden kullanmak daha kolaydır (ve parçaları ilk etapta bulmak).

19

Çünkü test kodu kod yazmaktan daha zor

Bir çok cevap, geliştiricinin bakış açısından iyi bir akıl yürütme sağladı - kodu, ilk etapta yazmaya daha yorucu hale getirme pahasına, bakım azaltılabilir.

Bununla birlikte, göz önünde bulundurulması gereken başka bir husus daha var - testler yalnızca orijinal kodunuz olarak ayrıntılı bir şekilde yapılabilir.

Her şeyi tek parça halinde yazarsanız, yazabileceğiniz tek etkili test "bu girdiler verildiğinde çıktı doğru mu?" Olur. Bu, bulunan herhangi bir hatanın "o devasa kod yığınında bir yere" dahil edildiği anlamına gelir.

Tabii ki, daha sonra bir geliştiricinin bir hata ayıklayıcı ile oturmasını ve sorunun tam olarak nerede başladığını ve bir düzeltme üzerinde çalışmasını sağlayabilirsiniz. Bu çok fazla kaynak gerektirir ve geliştiricinin zamanının kötü kullanımıdır. Şimdiye kadar gördüğünüz en küçük hatanın, tüm programın tekrar hata ayıklanmasına ihtiyaç duyan bir geliştirici ile sonuçlandığını hayal edin.

Çözüm: Her biri belirli, potansiyel bir başarısızlığı tespit eden birçok küçük test.

Bu küçük testler (örneğin Ünite Testleri), kod tabanının belirli bir alanını kontrol etme ve sınırlı bir kapsam dahilinde hataları bulmaya yardımcı olma avantajına sahiptir. Bu sadece bir test başarısız olduğunda hata ayıklamayı hızlandırmakla kalmaz, aynı zamanda tüm küçük testleriniz başarısız olursa - daha büyük testlerinizde arızayı daha kolay bulabileceğiniz anlamına gelir (yani belirli bir test edilmiş fonksiyonda değilse, etkileşimde olmalıdır). onların arasında).

Daha açık olması gerektiği gibi, daha küçük testler yapmak, kod tabanınızın daha küçük test gruplarına ayrılması gerektiği anlamına gelir. Bunu yapmanın yolu, büyük bir ticari kod tabanında, genellikle çalıştığınız şeye benzeyen bir kodla sonuçlanır.

Tıpkı bir not olarak: Bu, insanların işleri "fazla uzağa" almayacağı anlamına gelmez. Ancak, kod tabanlarını daha küçük / daha az bağlantılı parçalara ayırmanın meşru bir nedeni vardır - eğer makul şekilde yapılırsa.


5
Cevabınız sadece test ve test edilebilirliği ele alırken, diğer cevapların bazılarının tamamen göz ardı ettiği en önemli konu budur + 1.
skomisa

17

Lütfen bana açıkla, neden bu DDD tarzına, bir sürü kalıba ihtiyacımız var?

Birçoğumuz (çoğu ...) gerçekten onlara ihtiyacımız yok. Teorisyenler ve çok gelişmiş, deneyimli programcılar, çok sayıda araştırmanın ve derin deneyimlerinin bir sonucu olarak teoriler ve metodolojiler hakkında kitaplar yazar - bu, yazdıkları her şeyin günlük pratiklerinde her programcı için geçerli olduğu anlamına gelmez.

Küçük bir geliştirici olarak, bakış açınızı genişletmek için bahsettiğiniz kitap gibi kitapları okumak ve sizi belli konulardan haberdar etmek iyidir. Ayrıca, kıdemli meslektaşlarınız aşina olmadığınız terminolojiyi kullandığında sizi utandırmaktan ve aldatmaktan kurtaracaktır. Çok zor bir şey bulursanız ve mantıklı görünmüyor veya kullanışlı görünmüyorsa, bunun için kendinizi öldürmeyin - sadece kafanızda böyle bir kavram veya yaklaşımın olduğunu dosyalayın.

Günlük gelişiminizde, akademik olmadığınız sürece, işiniz uygulanabilir, sürdürülebilir çözümler bulmaktır. Bir kitapta bulduğunuz fikirler bu hedefe ulaşmanıza yardımcı olmazsa, çalışmanız tatmin edici olduğu sürece şu anda endişelenmeyin.

Okuduğunuz şeylerin bir kısmını kullanabileceğinizi ancak ilk başta "alamadım" veya belki kullanamadığınızı keşfedeceğiniz bir zaman gelebilir.


12
Saf düzeyde bu doğru olsa da DDD gibi geliyor ve diğer Desenler sadece teori. Onlar değil. Okunabilir ve korunabilir kod elde etmek için önemli araçlardır.
Jens Schauder,

9
@PeteKirkham OPs ikilemi, tasarım modellerinin aşırı kullanımıdır . Gerçekten ihtiyacınız var mı AccountServiceFacadeInjectResolver(sadece işyerinde bir sistemde bulduğum gerçek bir örnek) - cevap muhtemelen hayır.
vikingsteve

4
@vikingsteve OP, genel tasarım kalıplarının aşırı kullanımı hakkında yorum yapan bir programlama gurusu değildir. OP bir çıraktır ve dükkanında aşırı kullanıldığını düşünüyor . Biliyorum ki acemi-ben bugünlerde yazdığım kod hakkında aynı şeyi düşünürdüm, ama acemi-çok fazla kişisel proje başarısız oldu, çünkü çok karmaşık bir hale geldiler.
R. Schmitz

3
@ R.Schmitz dedi ki, acemi bana çok iyi kişisel projeler yaptı, çünkü iyi tasarlanmış, organize, yapılandırılmış, OOP gibi şeyler yapmak için çok çaba harcadılar. Bunların hepsi araç. Düzgün bir şekilde anlaşılmaları ve kullanılmaları gerekir ve vidalamada fakir olduğu için kırıcıyı zorlukla suçlayabilirsiniz. Şaşırtıcı bir şekilde, bu basit şeyi anlamak için çok fazla içgörü ve deneyim gerekiyor gibi görünüyor :)
Luaan

3
@Luaan Zaten iyi tasarlanmış, organize edilmiş, yapılandırılmış, OOP umurunda olsaydın, o acemi-seni zorlukla çağırırdım, ama evet, aşırı derecede kötü. Bununla birlikte, soru, OP'nin bu sorunların hangi sorunları çözdüğünü gerçekten nasıl anlamadığı ile ilgilidir. Sebebini bilmiyorsanız, sebebi yok gibi görünüyor - ama aslında, henüz bilmiyorsunuz.
R. Schmitz

8

Sorunuz çok fazla temeli olduğu için, birçok varsayımla birlikte, sorunuzun konusunu açıklayacağım:

Tasarım desenlerinde neden bu kadar çok sınıfa ihtiyacımız var?

Biz değil. Tasarım desenlerinde çok fazla sınıf olması gerektiğini söyleyen, genel olarak kabul edilmiş bir kural yoktur.

Kodu nereye koyacağınıza ve görevlerinizi farklı kod birimlerine nasıl keseceğinize karar vermeniz için iki ana yol vardır:

  • Uyum: herhangi bir kod birimi (bir paket, bir dosya, bir sınıf veya bir yöntem olabilir) birlikte olmalıdır . Yani, belirli bir yöntemin bir görevi olmalı ve bunu iyi yapmalısınız. Herhangi sınıf sorumlu olmalıdır biri (yani ne olursa olsun) büyük konu. Yüksek uyum istiyoruz.
  • Eşleştirme: herhangi bir kod birimi mümkün olduğunca az birbirlerine bağlı olmalıdır - özellikle dairesel bağımlılıklar olmamalıdır. Düşük kavrama istiyoruz.

Bu ikisi neden önemli olmalı?

  • Uyum: çok fazla şey yapan bir yöntem (örneğin, GUI, mantık, DB erişimi vb. Uzun bir kod karmaşasında tümüyle eski moda bir CGI betiği) uygunsuz hale gelir. Yazarken, düşünce treninizi uzun bir yönteme koymanız çok caziptir. Bu işe yarar, sunması kolay ve böyle bir şey olabilir. Sorun daha sonra ortaya çıkıyor: birkaç ay sonra, yaptıklarınızı unutabilirsiniz. En üstteki kod satırı, alttaki bir satırdan uzakta birkaç ekran olabilir; tüm detayları unutmak kolaydır. Yöntemin herhangi bir yerinde herhangi bir değişiklik, karmaşık şeyin herhangi bir davranışını bozabilir. Yöntemin bölümlerini yeniden incelemek veya yeniden kullanmak oldukça zor olacaktır. Ve bunun gibi.
  • Kuplaj: bir kod birimini her değiştirdiğinizde, ona bağlı olan diğer tüm birimleri potansiyel olarak kırmalısınız. Java gibi katı dillerde, derleme sırasında ipuçlarını alabilirsiniz (örneğin, parametreler, bildirilen istisnalar vb.). Ancak pek çok değişiklik, bu tür tetikleyicileri (yani davranışsal değişimleri) ve diğer, daha dinamik dilleri, böyle olanaklara sahip değildir. Bağlantı ne kadar yüksek olursa, herhangi bir şeyi değiştirmek o kadar zorlaşır ve bir hedefe ulaşmak için tam bir yeniden yazmanın gerekli olduğu yerde durma noktasına gelebilirsiniz.

Bu iki yön, herhangi bir programlama diline ve herhangi bir paradigmaya (sadece OO'ye değil) herhangi bir “nereye koyacağına” herhangi bir seçim için temel “sürücüler” dir. Herkes açıkça bunlardan haberdar değildir ve bunların yazılımları nasıl etkilediğine dair gerçekten kökleşmiş, otomatik bir his edinmeleri zaman alır, genellikle yıllar alır.

Açıkçası, bu iki kavram size gerçekte ne yapmanız gerektiği hakkında hiçbir şey söylemez . Bazı insanlar çok fazla, bazıları çok az. Bazı diller (burada size bakmaksızın, Java) dilin kendisinin son derece statik ve bilgiçlik yapısından dolayı birçok dersi tercih etme eğilimindedir (bu bir değer ifadesi değildir, ancak olduğu gibidir). Bu özellikle dinamik ve daha etkileyici dillerle, örneğin Ruby ile karşılaştırdığınızda farkedilir hale geliyor.

Diğer yönü bazı insanlar gereklidir kod yazmadan sadece çevik yaklaşımı abone olduğunu şu anda , ve ağır sonradan gerektiğinde refactor. Bu gelişim tarzında, interfaceyalnızca bir uygulayıcı sınıfa sahip olduğunuzda bir zaman yaratmazsınız . Sadece somut sınıfı uygularsınız. Daha sonra ikinci bir sınıfa ihtiyacınız olursa, yeniden yönlendirici olursunuz.

Bazı insanlar bu şekilde çalışmıyor. Daha genel olarak kullanılabilecek her şey için arayüzler (veya daha genel olarak soyut temel sınıflar) oluşturur; Bu hızla bir sınıf patlamasına yol açar.

Yine, aleyhte ve aleyhte argümanlar vardır ve hangisini tercih ettiğimin önemi yoktur. Yazılım geliştirici olarak hayatınızda, uzun spagetti yöntemlerinden, aydınlanmış, yeterince büyük sınıf tasarımlarına, çok fazla incelenmiş inanılmaz derecede gelişmiş sınıf şemalarına kadar tüm uç noktalarla karşılaşacaksınız. Daha fazla deneyim kazandıkça, "mimari" rollere doğru daha fazla büyüyeceksiniz ve bunu istediğiniz yönde etkilemeye başlayabilirsiniz. Kendiniz için altın bir orta bulacaksınız ve ne yaparsanız yapın birçok insanın sizinle aynı fikirde olmaya devam edeceğini göreceksiniz.

Bu nedenle, açık fikirli olmak, buradaki en önemli şeydir ve bu, size öneriyorum, konuyla ilgili çok fazla acı çekmiş gibi görünüyorsunuz, sorunuzun geri kalanını değerlendirerek ...


7

Deneyimli kodlayıcılar şunları öğrendi:

  • Çünkü bu ufacık programlar ve clases, özellikle başarılı olanları büyümeye başlar. Basit bir seviyede çalışan basit modeller ölçeklenemez.
  • Zira her ekleme / değiştirme için çeşitli eserler eklemek / değiştirmek zorunda kalmak zor görünebilir, ancak ne ekleyeceğinizi bilirsiniz ve bunu yapmak kolaydır. 3 dakikalık yazım, 3 saatlik akıllı kodlamayı geçiyor.
  • Küçük sınıfların birçoğu "dağınık" değildir, çünkü ek yükün neden iyi bir fikir olduğunu anlamıyorsunuzdur.
  • Alan bilgisi eklenmeden, 'bana açık' kodu ekip arkadaşlarım için gizemlidir ... ayrıca geleceği de.
  • Kabile bilgisi, ekip üyelerine hızlı ve verimli olmaları için ekip üyelerini kolayca ve zor bir şekilde eklemek için projeleri inanılmaz derecede zorlaştırabilir.
  • Adlandırma, bilgisayarcılıktaki iki zor problemden biri olarak hala doğrudur ve birçok sınıf ve yöntem çoğu zaman büyük bir fayda sağladığını adlandırmada yoğun bir alıştırmadır.

5
Ancak genel gider gerekli mi? Gördüğüm birçok durumda, tasarım desenleri aşırı kullanılıyor. Aşırı esnekliğin sonucu, kodu anlama, sürdürme, test etme ve hata ayıklama zorluğunun artmasıdır. Basit bir servis sınıfının (az önce gördüğüm gerçek bir örnek) etrafında 12 sınıf ve 4 maven modülünüz olduğunda, düşündüğünüzden daha kolay yönetilemez hale gelir.
vikingsteve

4
@vikingsteve Yapılandırılmış kodun genel olarak kötü bir fikir olduğunu kanıtlayacağını umarak hatalı bir uygulamanın tek bir örneğine atıfta bulunuyorsunuz. Bu sadece izlemiyor.
MetaFight

2
@ MetaFight OP yapı kodundan bahsetmiyor. Çok fazla soyutlama olarak gördüğü şey hakkında konuşuyor. Çok fazla soyutlamanız varsa, iddia ediyorum ki, çok hızlı bir şekilde çok yapılandırılmamış kodlar ve hemen hemen aynı parçalar elde edersiniz, çünkü insanlar başa çıkmak zorunda oldukları şeylerle başa çıkamazlar.
Daha

4
@Clearer Burada herkesin yapısal kodun varsayımsal yanlış uygulanmasının kötü bir şey olduğu konusunda hemfikir olduğuna eminim. OP onların Junior olduğunu söylüyor. İşte bu yüzden insanlar, yapılandırılmış kodun yararlarını bilmediğini ve yinelendiğini varsayıyor.
MetaFight

2

Şimdiye kadarki cevaplar, hepsi iyi, danışanın da kabul ettiği bir şeyin eksik olduğu varsayımıyla başladı. Ayrıca, askerin temelde haklı olması da mümkündür ve bu durumun nasıl ortaya çıkabileceğini tartışmaya değer.

Tecrübe ve uygulama güçlüdür ve eğer yaşlılar olayları kontrol altında tutmanın tek yolunun bol miktarda olduğu büyük, karmaşık projelerde deneyimlerini EntityTransformationServiceImplkazanırlarsa, tasarım desenleri ve DDD'ye yakınlık ile hızlı ve rahat olurlar. Küçük programlar için bile hafif bir yaklaşım kullanarak daha az etkili olurlar. Garip olanı olarak uyum sağlamalısınız ve bu harika bir öğrenme deneyimi olacak.

Yine de adapte olurken, tek bir yaklaşımı derinlemesine öğrenme arasındaki dengede bir ders olarak almalısınız, her yerde çalışmasını sağlayabileceğiniz bir noktaya kadar, çok yönlü kalmak yerine ve hangi araçların kullanılabileceğini bilmek zorunda değilsiniz. Hem dünyada hem de her ikisine de ihtiyaç duyulan avantajlar var.


-4

Kullanım başına daha fazla sınıf ve işlev yapmak, sorunları gelecekte çözülmesine yardımcı olacak belirli bir şekilde çözmek için mükemmel bir yaklaşım olacaktır.

Çoklu sınıflar temel çalışmaları olarak tanımlamaya yardımcı olur ve herhangi bir zamanda herhangi bir sınıf çağrılabilir.

Bununla birlikte, eğer birçok sınıf ve kendi getable adından fonksiyonlarsanız, arama ve yönetmeleri kolaydır. Buna temiz kod denir.


9
Üzgünüm ama ne diyorsun?
Deduplicator

@Deduplicator, kalıtımları için jframes thread ve sınıfları kullanıyorsak, java'da bir örnek alalım. Sadece bir sınıftan bazı java eserlerini tasarım için kullanamıyoruz, bu yüzden daha fazla ders yapmamız gerekiyor
Sanjeev Chauhan

2
Bu cevabın, daha net İngilizce olarak sunmayı iddia ettiği fikrini / fikirlerini sunması gerekir. Cevaptaki temel fikir, her biri iyi tanımlanmış bir işlevselliğe sahip olan küçük sınıfların iyi bir fikir olduğu anlaşılıyor, ancak korkunç dilbilgisi bunu neredeyse imkansız kılıyor. Ayrıca, kendi başına bu iddia yeterli olmayabilir.
talonx
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.