Hangi tasarım desenleri en kötü veya en dar tanımlanmıştır? [kapalı]


28

Her programlama projesi için geçmiş programlama deneyimine sahip yöneticiler, projeniz için bazı tasarım desenleri önerdiklerinde parlamaya çalışırlar. Tasarım kalıplarını anlamlı bulduklarında veya ölçeklenebilir bir çözüme ihtiyaç duyduğunuzda seviyorum. Örneğin, Proxy'leri, Gözlemcileri ve Komut örneklerini olumlu bir şekilde kullandım ve bunu her gün yapıyorum. Ancak, bir nesneyi yaratmanın tek bir yolu varsa, bir fabrika gelecekte her şeyi kolaylaştırabilir, ancak kodu zorlaştırır ve ek yükler olduğundan, Fabrika modeli söylemek konusunda gerçekten tereddüt ediyorum.

Bu yüzden sorum, gelecekteki kariyerim ve etrafa rastgele kalıp isimleri atan menajer tiplerine verdiğim yanıtla ilgili olarak:

Hangi tasarım desenlerini kullandınız, bu sizi genel olarak geri attı mı? En kötü tasarım kalıpları hangileri, mantıklı oldukları tek durum dışında göz önünde bulundurmanız gerekenler (okuma: hangi tasarım kalıpları çok dar bir şekilde tanımlanmıştır)? (Sanki insanların tasarım kalıplarını en çok neyin rahatsız ettiğini görmek için genel olarak iyi bir Amazon ürününün olumsuz eleştirilerini arıyor gibiydim.) Ve burada Anti-Patterns hakkında değil, genelde düşündüğüm Patterns hakkında konuşuyorum. "iyi" desenler.

Düzenleme: Bazılarının cevapladığı gibi, sorun genellikle kalıpların "kötü" değil "yanlış kullanıldığı" şeklindedir. Sık sık yanlış kullanılan ve hatta kullanımı zor kalıpları biliyorsanız, aynı zamanda bir cevap olarak da kullanılabilir.


Çoğu kalıp gelecekteki değişimi bazı değişim eksenlerinde kolaylaştırır, ancak değişiklikleri diğer değişim eksenlerinde daha da zorlaştırabilir. Dört kitabın çetesi, bir örüntüün ne zaman uygulanabileceğini söylemede özellikle iyidir. Desenleri takip eden pek çok kitap bu noktayı özlüyor. Ziyaretçi kalıbını örnek olarak alın. Yeni ağaç geçiş algoritmaları eklemeyi kolaylaştırır, ancak ağaca yeni tür düğümler eklemeyi zorlaştırır. Aynı zamanda, geçiş algoritmalarının ağaçtan daha yüksek bir katmanda olmasına izin verir. Bu eksen boyunca değişiklikleri kolaylaştırmak için hangi değişim ekseninin en az kararlı olduğunu ve tasarımın dikkate alınmasına ihtiyacınız vardır.
Theodore Norvell

'Dörtlü Çete' kitabındakiler.
Miles Rout

Yanıtlar:


40

Kötü kalıplara inanmıyorum, kalıpların kötü uygulanabileceğine inanıyorum!

  • IMHO singleton , en çok istismara uğramış ve en yanlış uygulanan kalıptır. İnsanlar tekil bir hastalığa yakalanmış gibi görünüyorlar ve alternatifleri düşünmeden her yerdeki tekiller için olanakları görmeye başlıyorlar.
  • IMHO ziyaretçi kalıbı en dar kullanıma sahip ve neredeyse hiçbir zaman karmaşıklık haklı çıkmayacak. Güzel bir pdf kazanılmış olabilir burada . Gerçekten de, tüm verileri önceden bilmeden, veri yapısı üzerinde farklı işlemler yaparken, bildiğiniz bir veri yapısına sahip olduğunuzda geçilecekse, ziyaretçi desenine dövüş şansı verin. Bu güzel olsa da :)

Bu cevap için sadece GOF kalıplarını dikkate aldım. Olası bütün kalıpları da dikkate alacak kadar iyi tanımıyorum.


Ziyaretçiler için çok az kullanım görüyorum. Singletons ... beni işe alma. Durum biri için mükemmel değilse, kullanmayın.
Michael K

1
Ziyaretçi için çok az kullanım olabilir, ancak olduğu zaman kesinlikle problemleri çözer. Anladığım kadarıyla Vistor LINQ için şarttır.
quentin-starin

12
Ziyaretçi deseni, bir yazılım programındaki döngüsel karmaşıklığı azaltmak (veya ortadan kaldırmak) için kritik öneme sahiptir . Bir if / else ağacınız veya bir switch deyiminiz olduğunda, bir Ziyaretçinin yerine koyma olasılığı yüksektir, garantili uygulama ve derleme zamanı kontrolü sunar. Ziyaretçi tanıdığım en güçlü kalıplardan biri ve onu düzenli olarak harika bir şekilde kullanıyoruz. Bir rüyayı da test ediyor.
Les Hazlewood

@LesHazlewood O zaman Ziyaretçi sadece yetersiz programlama dilleri için bir geçici çözüm değil mi? ML benzeri diller (Haskell, SML, OCaml, vb.), Ziyaretçi'den daha basit kod üreten cebirsel veri tiplerine ("steroidler üzerinde birleşme") ve desen eşleştirmeye ("steroidler üzerinde geçiş") sahiptir, ancak derleyici tarafından tam olarak kontrol edilir. Ziyaretçiyle karşılaştırıldığında, paylaşma durumunu nesne özellikleri aracılığıyla el ile yönetmeniz gereken birçok yönteminiz yok. ML benzeri dillerde ve tüm durum ayrımlarının tamamlanması gerekir, aksi takdirde derlenmez.
vog

14

Diğer cevaplayıcıların daha önce bahsettiği Singleton ve Visitor'dan başka, "ünlü" tasarım kalıplarını da bilmiyorum. IMHO'nun en büyük problemleri, belirli bir tasarım deseninin "yanlış" olmasından değil, çok istekli kalıpları uygulayan geliştiricilerden kaynaklanıyor.

Neredeyse herkes, kalıplarla tanışırken “kalıp ateşi” aşamasından geçer. Dilimlenen ekmeklerden bu yana kalıpların en iyisi olduğunu düşünerek, ilk bakışta bir olasılık gördüğü zaman bunları uygulamaya çalışır. Bu, kodların, kalıpların kendilerinin artık yardımcı olamadığı kalıpların altına gömülmesine neden olur; kodun uzun vadede anlaşılmasını ve sürdürülmesini zorlaştırır.

Sonunda, çoğumuz bu aşamayı geçiyor ve kendi problemleri için değil, gerçek problemleri çözmek için kalıpları nasıl kullanacağımızı öğrenmeye başlıyor. Kalıplar karmaşıklık eklenmiş olan fiyatlarına sahiptir ve herhangi bir belirli kalıp uygulama, sadece sistemin diğer bir bölümünü basitleştirmeye yardımcı olarak ek karmaşıklık için geri ödeme yapıldığında haklı kılınmakta, böylece kodun / yapılandırmanın genel olarak anlaşılmasını ve sürdürülmesini kolaylaştırmaktadır. Bu durumda değilse, kalıplardan uzak durmak, muhtemelen işe yarayabilecek en basit çözümle yapışmak daha iyidir.


Kesinlikle. Desenler iyi ya da kötü değildir, iyi uygulanır ya da yanlış uygulanır.

İnsanlara öğrendiğim yolu öğretmeyi tercih ederim: İlk önce OO, nesnenin nasıl birleştiğini anlamak ve sonra kalıpların adlarını öğrenmek. Yapılması gerekenden daha örüntüler açısından düşünmek çok kolaydır. Onlar bir iletişim aracıdır.
Michael K

Desenler, kuralcı bir liste değil, iletişim kurmanın bir yoludur. Eğer varsa başlamak aklında bir desenle, bunu misapplying olabilir. Eğer varsa bulmak tasarımınızda birini veya birinin ipuçları, daha sonra desen katalogları size gerekebilir başka ne anlamanıza yardımcı olabilir.
Rob Crawford

14

Burada uzuvdan çıkacağım ve kalıtımın aşırı kullanılmasını önereceğim. Kesinlikle en çok Java gibi katı derleme zamanı polimorfizm desteği olmayan dillerde uygulanabilir. Çalışma zamanı devralma, bir özellik değil, hepsine uyan bir özelliktir.

Diğer insanlar zaten Singletons'a olan nefretime benzer bir şekilde ifade ettiler, bu yüzden burada bunun üzerine genişlemeyeceğim.


10

Singleton. Şimdi daha sık olarak anti-desen olarak adlandırılan GOF kalıpları üzerindedir. Bunun nedenlerinden biri, Singleton'ın kodu test etmesini zorlaştırmasıdır.


4
Singleton modelinde çok sayıda temel kusur vardır, çoğu bu makalede Steve Yegge - Singleton
ocodo'da

Slomojo: Güzel yazı. Bundan sonra 'basit desen' diyeceğim:-)
Hiç kimse

2
Evet, çünkü bazı aptallar bir deseni yanlış kullanır ve OO'nun ne hakkında olduğu konusunda tekneyi tamamen özlüyor (geldiği tüm Yönetici sınıflarına göre değerlendiriliyor), Tabii ki bu geliştiricilerin değil, kalıbın hatası.
Dunk,

Neden herkes Singleton'un ortak (ve sıkıntılı) uygulamasını Singleton deseniyle ilişkilendirir? Biri neredeyse her zaman kötüdür, diğeri değil.
quentin-starin

1
@qes> Singleton önemli uygulama sorunlarına neden olur (özellikle diş açarken). Bu zaten kötü bir nokta. Ancak, singleton'un sınıfın nasıl işlediğine değil, sınıfın nasıl işlendiğine dair bir kalıp olduğunu göreceksiniz. Sınıfın nasıl kullanıldığı, sınıfın kullanıldığı kod tarafından ele alınmalıdır, bu yüzden Singleton endişelerin ayrılmasından kaynaklanır.
deadalnix

7

Sık sık yanlış kullanılan ve hatta kullanımı zor kalıpları biliyorsanız, aynı zamanda bir cevap olarak da kullanılabilir.

Aşağıdaki MVVM desen için WPF örneğin belirtildiği gibi, çok sıkı bu soruya tarafından . Bazı insanlar, hiçbir kodun koda çok sıkı bir şekilde konulmaması gerektiği ve her türlü egzotik hacklerin ortaya çıkması gerektiği yönergesini izlemeye çalışır.

Ve elbette, MVVM cehennem kadar zordur ve küçük kısa vadeli projeler için buna değmez.

WPF, MV-poo adlı makalesinde ironik bir yazı yaptı .


@Akku: Nasıl kullanılacağını bilmek zorundasın, bu yüzden projene uygun olup olmadığına karar verebilirsin. Yani evet, WPF gelişimi için şarttır ve çok faydalıdır.
Steven Jeuris

Sorunlardan biri, insanların MVVM modelini yanlış anlamalarıdır. "Cehennem kadar zor" değil. İnsanlar, Komuta Deseni ve Aracılık Deseni gibi diğer tüm modellerin bunun bir parçası olduğunu düşünerek bu şekilde yaparlar. Tek başına, MVVM bence en basit kalıplardan biri. Kabul ediyorum, bir şeyi takip etmenin aptalca olduğunu düşünüyorum.
BK

5

GOF kitabındaki kalıpların bazıları C ++ 'a özgüdür, yani yansıması olan dillerde daha az uygulanabilirler, örn. Prototip kalıp Java'da daha az önemlidir.

Tercüman modelini 'dar' bir model olarak görüyorum. Genel bir problem çözücüyü geliştirmeye değer genel bir probleminiz olmalıdır. Yalnızca bir dil icat edebileceğiniz, dilbilgisi tanımlayabileceğiniz ve tercüman yazabileceğiniz özel problemler için işe yarar. Sorun örnekleri dilbilgisinde bir cümle olarak gösterilmelidir. Bu tür durumlara sıklıkla rastladığınızı sanmıyorum.


1
GOF’un çoğu yalnızca statik sınıf tabanlı OOP’a uygulanabilir. Bu tür dillerden çok az sapmışsınız ve kitap sadece bir eğlence anıtı haline geliyor.
Javier,

5

En sık pişman olduğum (en şiddetli olmasa da): Ne zaman yeni bir işlev yaratmalıydım ama bir OOP çözümü uyguladım.


1
Niye ya? Seni pişman eden ne? Lütfen cevabınızı genişletin ve deneyiminizi ekleyin.
Walter,

Gerçekten de, yerel değişkenlere ve açık yöntemlere sahip bir sınıfın, yeniden kopyalamanın, yalnızca kopyala yapıştır ile yeniden uygulanabilen tek bir 200 satır işlevinden çok daha kolay olduğunu ve çirkin ve kapsamlı görünmeyecek tek bir yeri olmadığını düşünüyorum.
Akku

2
KISS, önce onu bir işlev yapıp ardından bir sınıfa yeniden yansıtmanızı sağlar.
Eva

5

Fabrika. Sadece bir tür yaratan kod uyguladığını gördüm. Bu tamamen yararsız kod IMO. Çevrimiçi örneklerin çoğunun tamamen yerine getirilmesine yardımcı olmuyor. Pizza fabrikası mı?

Belki de fabrika bağımlılık enjeksiyonundan dolayı test etmek daha kolaydır. Ancak ihtiyacınız olmayacaksa bu kodu eklemek benim için anlamsız ve JMockit gibi sahte çerçeveler kullandığınızda test argümanı kaybolur. Bir programı ne kadar basit yaparsanız, o kadar iyi olur. Fabrikalar yalnızca daha çok sayıda tip ile gerçekten anlamlıdır (daha büyük, yani en az 2 den fazla).


Evet, Pizza fabrikası, Head First Design Pattern için teşekkürler ~
Niing

2

Singleton

Singleton hakkında diğerleriyle aynı fikirdeyim. Onları asla kullanmamalısın, sadece birkaç vaka ile sınırlı olmalı. Çoğu zaman tembel küreler olarak kullanılırlar.

İplik güvenliği, singletonlarla ilgili bir konudur. İstisna işleme başka bir şeydir - eğer singleton düzgün bir şekilde oluşturamazsa - hatayı güvenli bir şekilde yakalayıp yakalayamayacağınızı, özellikle de "ana" den önce oluşturulan nesnelerden biri olup olmadığını her zaman bilemezsiniz. Ve daha sonra temizlik sorunu var.

Bir singleton kullanmayı tercih ediyorum ve diğer tüm "wannabe" singletons "un bir tanesine abone olmasını istiyorum. En yaygın singleton kullanımı, "shout olayı" kullanımıdır: siz sadece bir etkinliğin gerçekleştiği "dünyaya yayın yaparsınız" ve olayı dinleyen herkes böyle yapar. Bu şekilde, gerçekte gerçekleşen olayları, onları dinleyenlerle birleştirirsiniz. (Günlüğe kaydetme, sinyaller vb.)

Ziyaretçi

Bu konuda bulduğum çirkin şey, geliştiricilerin anlamlı isimleri düşünmemeleri ve sadece çağrı yöntemlerini ziyaret etmeyi () ziyaret etmeleri dışında, bir yönde genişletirken bir yönde genişletilebilirlik eklemesi, yani başka işlevsellik eklemesi, ziyaretçilerinizin ziyaret edebileceği tüm nesne türleri hakkında bilmesi gereken nesnelerin sayısı.

Dağınık olmasına rağmen, uzantıyı her iki yönde de kullanmak mümkündür, ancak bu, ziyaretçi biçimini normal biçimde kullanmaz. Bunun için en yaygın uygulama, nesneleri basmaktır: nesneleri ve yazdırılması gereken farklı nesneleri basmak için farklı yöntemleriniz vardır. Bunu her iki yönde de genişletebilmelisiniz. (Yazdırma, herhangi bir nesneyi bir akıma dönüştürmek anlamına gelir: bir dosyada / yazıda konsola / GUI'ye vb. Koymak).

(Not: Bunu, biraz farklı bir desen olan belge görüntüleme mimarisiyle karıştırmamalısınız).


2
Çözümünüz eskileri kullanır, bazı şeyleri tartışmaya sokar. Özellikle, bir etkinlik gönderirsiniz ve başka biri bu olayı ele alır ve günlüğe kaydeder. Bu iyi bir şey, çünkü herkes ayrıldı! YANLIŞ! Bunu yapardım, ne kadar acı bir acı oldu. Bir şeylerin kaydedilmesini istiyorsam, tam olarak bu noktada, şu anda, tam olarak gerçekleştiği kodda oturum açmak istediğimi fark ettim. Başka bir nesnenin kaydedilmemesi gerektiğini, hatta başkaları tarafından bile kaydedilmişse diğer işleyicilerin araya sokabileceği olası başka olayların bulunmadığını çözemezsiniz. Çok fazla abartılı tasarımdan başka bir şey değil.
Dunk

2

Daha karmaşık kalıpların bazılarındaki problemin, iletişim aygıtları olarak değerlerinin çoğunu kaybedecekleri çok fazla varyasyonun olduğunu düşünüyorum.

Bu kategoride aklıma gelen en kötü suçlu MVC paterni. MVP'yi görmezden gelsek bile, bu öğelerin her birinin rolünde, sınırların nerede olduğunu bulmak için her yeni çerçevede bir saat harcamak zorunda olduğunuz çok fazla değişiklik var.


Ayrıca MVC'nin her yerde kullanılması gerektiğini ama her yerde aynı şekilde uygulanmaması gerektiğini düşünüyorum. Ve birçok insan bunu anlamıyor. İlk kullanmak istediğimde, Model, View (bir windows form) ve Controller adlı üç sınıf yaptım. MVC için formlar oluşturulmadığı için bir karışıklık oldu.
Akku

1

Kötü modeller yok, sadece kötü insanlar var.

Açıkça net bir şeyler yapan, ancak biraz ezilmiş püre yerine tekrar kullanılabilir (gasp!) (Sıra kötü villian müziği) olan biraz ayrıntılı ya da olmayan (kolayca okunabilir kod) miras alırdım InheritAbstractTemplateFaucetSink<Kitchen>.

Yeniden kullanılabilir kod harika! Muhtemelen, yeniden kullanılacak bir kod yazmıyorsunuz veya başka bir uygulamanın benzer mantığını tekrar yazıyorsanız, başka bir uygulamanın kodunu yeniden kullanmaya çalışmaktan daha az zaman alacaksınız.

Daha fazla okuma çatlağı için bazı C kodunu posix başlıklarının veya uçurumların akıllı uygulamalarında açın ve deseni görün. Bu kod, dünyadaki en zeki ve en özel programcılar tarafından yazılmıştır. Kaç tane Soyut Fabrika Örüntüsünü göreceğinizi biliyor musunuz? ... YOK!. Neler olup bittiğini diğer kısımlarını anlarsanız, daha iyi şanslar bile, mantığı anlaması ve izlemesi çok kolay bulacaksınız.

Demek istediğim, bu "kalıpların" çoğunun kodları daha iyi hale getirmek için yaratılmadıkları, kitap satmak ve modelleme yazılımı oluşturmak için yaratıldıkları. Programlamada iyiyseniz, muhtemelen bunların çoğundan kaçınacak ve probleminizi çözen net, özlü ve akıllıca tasarlanmış bir kod yazacaksınız. Başka bir probleminiz olduğunda, bu problemi çözmek için açık, özlü, zekice tasarlanmış bir kod yazacaksınız. Amacınız daha az kod yazmaksa, bence bir programcı olmaktan vazgeçmediğinizi düşünürdüm. Kod yazmayı seviyorum ve mümkün olduğunca yazmak istiyorum. Zaten yazmış olduğum bir şeyi tekrar yazdığımda, onlarca kez hızlı yapıyorum ve ilk yaptığımda mutlu olmadığım her şeyden kurtuluyorum.

Bununla, bilgisayar bilimlerinde muhtemelen en iyi (ilgili) teklifi vereceğim.

Bir yazılım tasarımı yapmanın iki yolu vardır: Bir yol, açık bir şekilde hiçbir eksiklik olmayacak kadar basit hale getirmektir ve diğer yol, belirgin bir eksikliğin olmadığı kadar karmaşık hale getirmektir. İlk yöntem çok daha zor . "

  • Tony Hoare (quicksort'un mucidi, modern işletim sistemi tasarımının babası, Hoare mantığının yaratıcısı ve Turing ödülü alıcısı)

0

Çoğu model için bir zaman olduğu ve birçok modeli kötüye kullanabileceğinize kesinlikle katılıyorum. Geçmişte en çok kötüye kullandığımın Soyut Şablon kalıbı olduğunu biliyorum. Tam olarak alındığında ASP.NET webformları olarak bilinir.

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.