Muhtemelen 23 arayüz uygulayan bir sınıfa sahip olmak için bir kod kokusu veya hatta bir anti-patern olduğunu düşünürdüm. Gerçekten bir anti-kalıp ise, ona ne derdiniz? Yoksa sadece Tek sorumluluk ilkesini izlemiyor mu?
Muhtemelen 23 arayüz uygulayan bir sınıfa sahip olmak için bir kod kokusu veya hatta bir anti-patern olduğunu düşünürdüm. Gerçekten bir anti-kalıp ise, ona ne derdiniz? Yoksa sadece Tek sorumluluk ilkesini izlemiyor mu?
Yanıtlar:
Kraliyet Ailesi: Özellikle çılgınca bir şey yapmazlar ama bir milyar başlıkları vardır ve bir şekilde diğer kraliyetlerle ilgilidir.
somehow
Bu anti-paternin Tüm İşlemler Jack'i veya belki de Çok Fazla Şapka adını verdim.
Eğer bir isim vermek zorundaysam, Hydra diyebilirim :
Yunan mitolojisinde, Lernaean Hydra (Yunanca: Ὕδρναία Ὕδρα) sürüngen özellikleri olan eski bir isimsiz yılan gibi chthonic su canavarıydı; boya ve her kafa kesti için iki tane daha büyüdü - ve zehirli bir nefes aldı ki izleri bile ölümcül oldu.
Özellikle alaka düzeyi, sadece birçok kafaya sahip olması değil, aynı zamanda daha fazla büyümeye devam etmesi ve bu yüzden öldürmesi imkansız olması gerçeğidir. Bu tür tasarımlarla olan deneyimim buydu; geliştiriciler, ekrana sığmayacak kadar çok daha fazla arayüzü sık sık tutmaya devam ediyor ve o zamana kadar programın tasarımında ve onu bölmenin umutsuz bir umut olduğu varsayımlarına çok derinlemesine girmeye başladı (denerseniz, aslında genellikle boşluğu kapatmak için daha fazla ara yüze ihtiyaç duyarız).
Bir "Hydra" nedeniyle yaklaşmakta olan kıyametin erken bir işareti, bir arayüzün diğerine, fazla akıl kontrolü olmadan ve çoğu zaman, aşağıdaki gibi olduğu gibi mantıklı olmayan bir hedefe sık sık dökülmesidir:
public void CreateWidget(IPartLocator locator, int widgetTypeId)
{
var partsNeeded = locator.GetPartsForWidget(widgetTypeId);
return ((IAssembler)locator).BuildWidget(partsNeeded);
}
Bağlamdan çıkarıldığında, bu kodla ilgili balık içeren bir şey olduğu açıktır, ancak bunun gerçekleşmesi olasılığı, bir nesnenin büyüdüğü "kafalarla" artar, çünkü geliştiriciler sezgisel olarak her zaman aynı yaratıkla ilgilendiklerini bilirler .
İyi şanslar hiç bir nesne olduğunu uygular 23 arayüzleri üzerinde herhangi bir bakım yapıyor. Sürecinde teminatın zarar görmemesi ihtimali hiç de zayıf.
Tanrı Nesne akla gelen; HER ŞEYİ nasıl yapacağını bilen tek bir nesne. Bu, iki ana tasarım metodolojisinin "uyum" gereksinimlerine düşük bağlılıktan gelir; 23 arayüzlü bir nesneye sahipseniz, kullanıcılarına nasıl 23 farklı şey olduğunu bilen bir nesneye sahipsiniz ve bu 23 farklı şey muhtemelen sistemin tek bir görev veya alanı boyunca değil.
SOLID'de, bu nesnenin yaratıcısı açıkça Arayüz Ayrıştırma İlkesini izlemeye çalışmış olsa da, önceki bir kuralı ihlal etmişlerdir; Tek Sorumluluk İlkesi. Bunun "KATI" olmasının bir nedeni var; Tasarım hakkında düşünürken her zaman önce S gelir ve diğer tüm kurallar takip eder.
GRASP'da, böyle bir sınıfın yaratıcısı "Yüksek Uyum" kuralını ihmal etmiştir; GRASP, SOLID'den farklı olarak, bir nesnenin tek bir sorumluluğu bulunmadığını öğretir, ancak en fazla iki ya da üç çok yakın ilişkili sorumluluğu olması gerekir.
23 Sadece bir sayı! Büyük olasılıkla senaryoda, alarm verecek kadar yüksektir. Bununla birlikte, sorarsak, bir "kalıp karşıtı" olarak adlandırılan bir etiketi almadan önce en fazla sayıda yöntem / arayüz nedir? 5 ya da 10 ya da 25 mi? Bu sayının gerçekten bir cevap olmadığını fark edersiniz, çünkü 10 iyiyse, 11 de olabilir - ve bundan sonra herhangi bir tamsayı.
Asıl soru karmaşıklıkla ilgilidir. Ve uzun kodun, metot sayısının veya herhangi bir önlemle sınıfın büyüklüğünün aslında karmaşıklığın tanımı OLMADIĞINI belirtmeliyiz . Evet, daha büyük ve daha büyük kod (daha fazla sayıda yöntem) yeni bir acemi için okumayı ve kavramayı zorlaştırır . Ayrıca, potansiyel olarak çeşitli işlevsellik, çok sayıda istisna ve çeşitli senaryolar için oldukça gelişmiş algoritmalar da kullanmaktadır. Bu karmaşık olduğu anlamına gelmez - sadece sindirimi zordur.
Diğer taraftan, birkaç saat içinde okumayı ümit edebileceğiniz nispeten küçük boyutlu kod hala karmaşık olabilir. İşte kodun (gereksiz yere) karmaşık olduğunu düşünüyorum.
Nesne yönelimli tasarımın her bir bilgeliği buraya "karmaşık" tanımlamak için yerleştirilebilir, ancak burada "çok sayıda yöntemin" karmaşıklığın bir göstergesi olduğunu göstermek için kısıtlardım.
Karşılıklı Bilgi (aka eşleştirme) Her şey bir şeyler sınıf olarak yazıldığında, hepimizin "güzel" nesne yönelimli kod olduğunu düşünüyoruz. Ancak, diğer sınıfla ilgili varsayım, esasen gerçek ihtiyaç duyulan kapsüllemeyi bozuyor. Algoritmaların iç durumu hakkında derinlemesine "sızdıran" metotlara sahip olduğunuzda - ve uygulama, hizmet veren sınıfın içsel durumu ile ilgili temel varsayımlarla inşa edilir.
Çok fazla yineleme (zorla girme) Benzer adlara sahip, ancak işle çelişen veya benzer işlevli isimlerle çelişen yöntemler olduğunda. Çoğu zaman kodlar, farklı uygulamalar için biraz farklı arayüzleri desteklemek üzere gelişir.
Çok fazla rol Sınıf, yan işlevler eklemeye devam ettiğinde ve onun gibi insanlar kadar genişlemeye devam ettiğinde, yalnızca sınıfın gerçekten de iki sınıf olduğunu bilmek. Şaşırtıcı bir şekilde, bunların hepsi gerçek ile başlargereksinimleri ve bunu yapmak için başka bir sınıf yok. Bunu düşünün, işlemin ayrıntılarını anlatan bir İşlem sınıfı vardır. Şimdiye kadar iyi görünüyor, şimdi birileri "işlem zamanında" (UTC ve benzerleri arasında) format dönüşümüne ihtiyaç duyuyor, daha sonra insanlar bazı işlemlerin geçersiz kılmak için belirli tarihlerde olup olmadığını kontrol etmek için kurallar ekliyor. - Tüm hikayeyi yazmayacağım ama sonunda, işlem sınıfı içinde tüm takvimi oluşturuyor ve ardından insanlar "sadece takvim" bölümünü kullanmaya başlıyor! Bu çok karmaşık (hayal etmek için) neden bir "takvim" in bana sağlayacağı bir işlevselliğe sahip olmak için "işlem sınıfı" nı başlatacağım!
(In) API tutarlılığı book_a_ticket () yaptığımda - Bir bilet tutarım! Bu, gerçekleşmesi için kaç tane kontrol ve işlem yapıldığına bakılmaksızın, çok basit. Şimdi zaman akışı bunu etkilemeye başladığında karmaşık bir hal alıyor. Tipik bir, ve olası mevcut / kullanılamaz durum "arama" sonra tekrar-n-ileri bir sonra bilet içindeki bazı bağlam işaretçileri kaydetmeye başlar azaltmasına olanak sağlayacak başvurmak bilet kitaba söyledi. Ara tek işlevsellik değildir; bu tür birçok "yan işlevsellik" den sonra işler daha da kötüye gider. Bu süreçte book_a_ticket () anlamı book_that_ticket () anlamına gelir! ve bu düşünülemez derecede karmaşık olabilir.
Muhtemelen, çok gelişmiş bir kodda göreceğiniz birçok durum vardır ve pek çok kişinin senaryolar ekleyebileceğinden eminim, "çok fazla yöntem" in mantıklı gelmediği veya açıkça düşündüğünüzü yapmadığı durumlar. Bu anti-kalıptır.
Benim kişisel deneyimim, oldukça aşağıdan yukarıya doğru başlayan projeler başladığında , gömülü veya daha kötülerinde gerçek sınıflar olması gereken birçok şeyin farklı sınıflar ve eşleşme artışları arasında hala bölünmüş kalmasıdır. Çoğu zaman 10 sınıfı hakedecek olan, ancak sadece 4 olan, birçoğunun çok amaçlı kafa karıştırıcı ve çok sayıda metoda sahip olması muhtemeldir. Bir TANRI ve DRAGON olarak adlandırın, BAD budur.
AMA özenle tutarlı ÇOK BÜYÜK sınıflarına rastlıyorsunuz, 30 yöntemleri var - ve hala çok temiz. İyi olabilirler.
Sınıflar tam olarak doğru sayıda arayüze sahip olmalıdır; ne fazla ne az.
"Çok fazla" demek, bu arayüzlerin hepsinin o sınıfta yararlı bir amaca hizmet edip etmediğine bakmadan imkansız olurdu. Bir nesnenin bir arabirim uyguladığını bildirmek, sınıfın derlemesini beklerseniz, yöntemlerini uygulamanız gerektiği anlamına gelir. (Baktığınız sınıfı yapar sanırım.) Arayüzdeki her şey uygulanırsa ve bu uygulamalar sınıfın içindekilerine göre bir şey yaparsa, uygulamanın orada olmaması gerektiğini söylemek zor olacaktır. Bu kriterleri karşılayan bir ara yüzün nereye ait olamayacağını düşünebildiğim tek vaka dışsal: kimse kullanmadığında.
Bazı diller, Java'nın extends
anahtar kelimesi gibi bir mekanizma kullanarak arayüzlerin "alt sınıflara alınmasına" izin verir ve bunu kim yazdıysa, bunu bilmiyor olabilir. Aynı zamanda, 23'ün hepsinin, onları bir araya getirmenin bir anlamı olmadığından, yeterince uzak tutulması olabilir.
Tipik bir "fasulye" için normal olduğu gibi her özellik için bir "alıcı" / "ayarlayıcı" çiftine sahip olduklarını düşündüğü gibi sesler ve tüm bu yöntemleri arabirime yükselttiler. Peki " fasulye " demeye ne dersin ? Veya çok fazla fasulyenin iyi bilinen etkilerinden sonra daha fazla Rabelaci "Yassılık".
Genel bir nesne farklı ortamlarda kullanıldığında, arabirimlerin sayısı genellikle artar. C # 'da IComparable değişkenleri, IEqualityComparer ve IComparer, farklı kurulumlarda sıralamaya izin verir, bu nedenle genel olarak güçlü olmayan sürümleri ve genel olmayan sürümleri uygulayabildiğinizden bazıları, bir kereden fazla olabilir. Ek olarak, jeneriklerden birden fazlasını uygulayabilirsiniz.
Örnek bir senaryo ele alalım, diyelim ki başka bir şey satın alabileceğiniz kredi alabileceğiniz bir web mağazası (stok fotoğraf siteleri genellikle bu şeması kullanır). Aynı temeli oluşturan bir "Valuta" ve "Kredi" sınıfına sahip olabilirsiniz. Valuta'da, "Para Birimi" özelliği hakkında endişelenmeden hesaplamalar yapmanıza izin veren bazı operatör aşırı yüklemeleri ve karşılaştırma rutinleri vardır (örneğin, dolarlara pound ekler). Krediler çok daha basittir ancak başka davranışları da vardır. Bunları birbirleriyle karşılaştırabilmek için, her ikisine de IComparable ve IComparable ve diğer karşılaştırma arayüzleri çeşitlerini uygulayabilirsiniz (temel sınıfta veya başka bir yerde olsa da ortak bir uygulama kullanıyor olsalar bile).
Serileştirme uygulanırken, ISerializable, IDeserializationCallback uygulanır. Sonra geri alma yığınlarını geri alma uygulaması: IClonable eklenir. IsDirty işlevselliği: IObservable, INotifyPropertyChanged. Kullanıcıların dizeleri kullanarak değerleri düzenlemelerine izin vermek: IConvertable ... Liste uzayıp gidebilir ...
Modern dillerde, bu yönleri ayırmaya ve onları kendi sınıflarına, çekirdek sınıfın dışına yerleştirmeye yardımcı olan farklı bir eğilim görüyoruz. Dış sınıf veya görünüş daha sonra açıklama (nitelikler) kullanılarak hedef sınıfla ilişkilendirilir. Çoğu zaman dış görünüş sınıflarını aşağı yukarı jenerik hale getirmek mümkündür.
Niteliklerin kullanımı (açıklama) yansımaya tabidir. Bir dezavantajı küçük (ilk) performans kaybı. (Genellikle duygusal) bir sakınca, kapsülleme gibi prensiplerin gevşetilmesi gerektiğidir.
Her zaman başka çözümler vardır, ancak her şık çözüm için bir takas veya bir tuzak vardır. Örneğin, bir ORM çözümü kullanmak tüm özelliklerin sanal olarak ilan edilmesini talep edebilir. Seri hale getirme çözümleri, sınıflarınızda varsayılan kurucuları talep edebilir. Bağımlılık enjeksiyonunu kullanıyorsanız, tek bir sınıfa 23 adet arayüz uygulayabilirsiniz.
Benim gözümde 23 arayüz tanım gereği kötü olmak zorunda değildir. Arkasında iyi düşünülmüş bir şema veya yansıma veya aşırı kapsülleme inançlarının kullanılmaması gibi bazı ilkeler belirlenebilir.
Ne zaman bir işi değiştirirseniz ya da mevcut bir mimariyi inşa etmek zorunda kalıyorsanız. Tavsiyem ilk önce tam olarak tanışmak, her şeyi çok hızlı bir şekilde yeniden denemeye çalışmayın. Orijinal geliştiriciyi dinleyin (hala oradaysa) ve gördüklerinizin arkasındaki fikir ve düşünceleri anlamaya çalışın. Sorular sorarken, bunu kırma uğruna değil, ama öğrenmek için yapın ... Evet, herkesin kendi altın çekiçleri vardır, ancak ne kadar çok çekiç toplarsanız meslektaşlarınızla ne kadar iyi anlaşırsanız o kadar kolaylaşırsınız.
"Çok fazla" özneldir: programlama tarzı? performans? standartlara uygunluk? emsal? sadece düz rahatlık duygusu / güven?
Kodunuz doğru davrandığı ve bakım sorunları olmadığı sürece, 23 norm bile olabilir. Bir gün daha sonra "23 arayüz ile mükemmel bir iş yapabilirsin, bakınız: Jonas Elfström" diyebilirim.
Limitin 23'ten daha küçük bir sayı olması gerektiğini söyleyebilirim - daha çok 5 veya 7 gibi,
ancak bu, bu arayüzlerin devraldığı herhangi bir sayıda arayüzü veya temel sınıflar tarafından uygulanan herhangi bir sayıda arayüzü içermez.
(Tamamen, N + herhangi bir sayıda kalıtsal arayüz, N <= 7'dir.)
Sınıfınız çok fazla arabirim kullanıyorsa, muhtemelen bir tanrı sınıfıdır .