Gevşek kavrama kasası anti-patern kullanıyor mu?


22

Gevşek kavrama, bazı geliştiricilere, iyi tasarlanmış bir yazılımın kutsal kâsesidir. Öngörülebilir gelecekte gerçekleşmesi muhtemel değişiklikler karşısında kodu daha esnek hale getirdiğinde ya da kod çoğaltmasını engellediğinde kesinlikle iyi bir şeydir.

Öte yandan, bileşenlerin gevşek bir şekilde bağlanma çabaları bir programdaki dolaylılık miktarını arttırır, böylece karmaşıklığı arttırır, bu da çoğu zaman daha kolay anlaşılmasını ve çoğu zaman daha az verimli olmasını sağlar.

Gevşek kuplaj için herhangi bir kullanım durumu olmadan gevşek kuplaj üzerinde odaklanmayı düşünüyor musunuz (örneğin kod çoğaltmasını önlemek veya öngörülebilir gelecekte gerçekleşmesi muhtemel değişiklikleri planlamak gibi). Gevşek kaplin YAGNI şemsiyesinin altına düşebilir mi?


1
Çoğu avantajın bir bedeli vardır. Avantaj, masraftan ağır basarsa kullanın.
LennyProgramcılar

4
gevşek kaplin madalyonunun çevirme tarafını unuttun ve high cohesiondiğeri olmayan, bir çaba kaybı ve illüstrasyonların ikisinin de anlama konusundaki temel eksikliği.

Yanıtlar:


13

Biraz.

Bazen çok fazla çaba sarf etmeyen gevşek bağlantı, bazı modüllerin sökülmesini talep eden belirli gereksinimleriniz olmasa bile iyidir. Düşük asılı meyve, olduğu gibi.

Öte yandan, gülünç miktarda değişim için fazla çalışmak, gereksiz yere karmaşıklık ve çaba harcayacaktır. YAGNI, dediğiniz gibi, kafasına vuruyor.


22

X programlama pratiği iyi mi yoksa kötü mü? Açıkçası, cevap her zaman "bağlıdır".

Kodunuza bakıyorsanız, hangi "kalıpları" enjekte edebileceğinizi merak ediyorsanız, o zaman yanlış yapıyorsunuz demektir.

Yazılımınızı, ilgisiz nesnelerin birbirleriyle dolaşmaması için oluşturuyorsanız, doğru şekilde yapıyorsunuz demektir.

Çözümünüzü “sonsuz” olarak genişletilip değiştirilebilecek şekilde “yapılandırıyorsanız”, o zaman gerçekten daha karmaşık hale getiriyorsunuz.

Bence günün sonunda tek bir gerçeğe sahipsin: Nesnelerin ayrıştırılması az çok karmaşık mı? Onları birleştirmek daha az karmaşıksa, o zaman bu doğru çözümdür. Onları ayırmak daha az karmaşıksa, bu doğru çözümdür.

(Şu anda oldukça karmaşık bir şekilde basit bir iş yapan oldukça küçük bir kod tabanında çalışıyorum ve bu kadar karmaşık hale getiren şeyin bir kısmı, orijinalin "çiftleşme" ve "uyum" terimlerinin anlaşılamaması. geliştiricileri.)


4
Geçen gün bunu yaptım: “sadece durumunda” iki sınıf arasında bazı indirmelere ihtiyacım olacağını düşündüm. Sonra kafamı bir şeyleri ayıklamaya çalışarak incittim, dolaysızlığı kırdım ve daha mutlu oldum.
Frank Shearar

3

Burada ne elde ettiğinizin uyum kavramı olduğunu düşünüyorum . Bu kodun iyi bir amacı var mı? Bu amacı içselleştirebilir ve neler olup bittiğini "büyük resim" anlayabilir miyim?

Takip etmesi zor bir koda yol açabilir, çünkü daha pek çok kaynak dosya olduğundan (bunların ayrı sınıflar olduğunu varsayarsak), ancak hiçbir sınıfın bir amacı olmadığı görülebilir.

Çevik bir perspektiften bakıldığında, bu kadar gevşek eşleşmenin bir anti-patern olacağını söyleyebilirim. Uyumluluk olmadan ve hatta bunun için kılıflar kullanmadan bile, mantıklı ünite testleri yazamazsınız ve kodun amacını doğrulayamazsınız. Şimdi, çevik kod, örneğin teste dayalı geliştirme kullanıldığında gevşek bağlantıya neden olabilir. Fakat doğru testler oluşturulduysa, doğru sırada, o zaman muhtemelen hem iyi bir uyum hem de gevşek birleşme söz konusudur. Ve sen sadece açıkça hiçbir uyum olmadığı durumlarda olan davalardan bahsediyorsun.

Yine çevik bakış açısına göre, bu yapay dolaylılık seviyesini istemezsiniz, çünkü muhtemelen herhangi bir şekilde ihtiyaç duyulmayacak bir şeye harcanır. İhtiyaç gerçek olduğunda refactor yapmak daha kolaydır.

Genel olarak, modüllerinizde yüksek kavrama ve aralarında gevşek kavrama istiyorsunuz. Yüksek kavrama olmadan muhtemelen uyumunuz olmaz.


1

Bu gibi soruların çoğunluğu için cevap “bağlıdır”. Genel olarak, mantıklı bir şekilde gevşek bir şekilde bir tasarım yapabilir, mantıklı bir şekilde, bunu yapmak için büyük bir yük olmadan, yapabilirim. Gereksiz kuplaj kodundan kaçınmak, aklıma göre, tamamen faydalı bir tasarım hedefidir.

Bileşenlerin mantıksal olarak sıkı bir şekilde bağlanması gerektiği gibi göründüğünde, onları parçalamaya başlamadan önce zorlayıcı bir argüman arayacağım.

Sanırım bu tür uygulamaların çoğuyla çalıştığım ilke ataletten biri. Kodumun nasıl çalışmasını istediğime dair bir fikrim var ve eğer hayatı daha da zorlaştırmadan bu şekilde yapabilirsem daha sonra yapacağım. Bunu yapmak gelişmeyi zorlaştıracak ancak bakım ve gelecekteki işleri kolaylaştıracaksa, kodun kullanım ömrü boyunca daha fazla çalışıp çalışmayacağını tahmin etmeye çalışacağım ve kılavuzum olarak kullanacağım. Aksi takdirde, üzerinde çalışmaya değecek kasıtlı bir tasarım noktası olması gerekecektir.


1

Doğru cevap, doğru bağlantı yapıldığında gevşek bağlantıdır.

Tek işlev prensibi varsa, bir amaç takip edilirse neler olduğunu takip etmek yeterince kolay olmalıdır. Ayrıca, gevşek çift kodu elbette herhangi bir çaba göstermeden elbette izler.

Basit tasarım kuralları: 1. Bir cephe arayüzü oluşturmadığınız sürece, birden fazla öğenin bilgisini tek bir noktaya (her yerde belirtildiği gibi değişir) oluşturmayın. 2. bir fonksiyon - bir amaç (bu amaç bir cephede olduğu gibi çok yönlü olabilir) 3. bir modül - bir ilişkili açık fonksiyonlar kümesi - bir açık amaç 4. basit bir şekilde test edemiyorsanız, o zaman basit bir amaç

Daha sonra refactor için daha kolay hakkında tüm bu yorumlar bir sürü kod. Bilgi bir çok yere, özellikle dağıtık sistemlere yerleştirildikten sonra, yeniden yapılandırma maliyeti, geri dönüş senkronizasyonu ve hemen hemen diğer tüm maliyetler, çoğu durumda sistemin bu nedenle çöpe atıldığını göz önüne almaz.

Bugünlerde yazılım geliştirmeyle ilgili üzücü olan şey, insanların% 90'ının yeni sistemler geliştirmesi ve eski sistemleri anlama yeteneğine sahip olmaması ve bitlerin ve parçaların sürekli olarak yeniden düzenlenmesi nedeniyle sistemin böyle kötü bir sağlık durumuna kavuşmadığı zamanlarda asla bulunmadığıdır.


0

Bir şey diğerine hiç değişmezse, bir şeyin diğerine ne kadar sıkı bağlı olduğu önemli değil. Yıllar geçtikçe genel olarak, işlerin değişmesi, istikrar arayışı için daha az neden aramaya odaklanmanın, mümkün olan en gevşek eşleşme biçimine ulaşmaya çalışarak değişmelerini kolaylaştırmaktan daha verimli olduğunu gördüm. Dekuplaj Paketleri ayırmak için bazen mütevazı kod çoğaltmayı tercih ettiğim noktaya çok faydalı buldum. Temel bir örnek olarak, matematik kütüphanemi bir resim kütüphanesi uygulamak için kullanma seçeneğim vardı. Kopyalamama önemsiz bazı temel matematiksel işlevleri yapmadım ve çoğalttım.

Artık resim kütüphanem matematik kütüphanesinden tamamen bağımsız, matematik kütüphanemde ne gibi değişiklikler yapsam da, resim kütüphanesini etkilemeyecek. Bu her şeyden önce istikrar koymak. Görüntü kütüphanesi, değişecek daha az nedene sahip olduğu için artık daha kararlıdır, çünkü değişebilecek başka bir kütüphaneden ayrılmıştır (umarım asla değişmemesi gereken C standart kütüphanesinin yanı sıra). Bir bonus olarak, onu oluşturmak ve kullanmak için bir sürü başka kütüphanenin çekilmesini gerektirmeyen tek başına bir kütüphane olduğunda dağıtmak da kolaydır.

Kararlılık bana çok yardımcı oldu. Gelecekte değişmesi için daha az ve daha az neden içeren iyi test edilmiş bir kod koleksiyonu oluşturmayı seviyorum. Bu kesin bir rüya değil; O zamandan beri hiç değişmeyen 80'li yılların sonundan beri tekrar kullandığım ve kullandığım C kodum var. Kuşkusuz, piksel seviyeli ve geometri ile ilgili kodlar gibi düşük seviyeli şeyler, yüksek seviyeli malzemelerimin çoğu eskimiş hale geldi, ama yine de etrafta olması için çok yardımcı olan bir şey. Bu neredeyse her zaman, hiçbir şey harici değilse, daha az ve daha az şeye dayanan bir kütüphane anlamına gelir. Yazılımınız gittikçe daha az değişikliğe neden olan veya hiç sebep bumayan sağlam temellere bağlıysa güvenilirlik artar. Daha az hareketli parça, pratikte hareketli parçaların sayısı sabit parçalardan çok daha fazla olsa bile, gerçekten çok güzel.

Gevşek kuplaj aynı damardadır, ancak sıklıkla gevşek kuplajın kuplajsız olmaktan çok daha az stabil olduğunu buluyorum. Daha önce çalıştığımdan çok daha üstün arayüz tasarımcıları ve aklını değiştirmeyen müşterilerden oluşan bir ekipte çalışmadığınız sürece, saf arayüzler bile çoğu zaman kod boyunca basamaklı bozulmalara neden olacak şekilde değişme nedenleri bulur. İstikrarın somuttan ziyade özete doğru yönlendirilmesiyle elde edilebileceği fikri, arayüz tasarımının uygulamadan ilk seferde doğru yapılması daha kolaysa kullanışlıdır. Bir geliştiricinin çok iyi yarattığı yerlerde, harika olsa da, yerine getirmeleri gerektiğini düşündükleri tasarım gereklilikleri yerine getirildiğinde, ancak gelecekte tasarım gerekliliklerinin tamamen değiştiğini bulmak için uygulamaların tersine döndüğünü gördüm.

Bu yüzden, istikrarı tercih etmeyi ve tamamen ayrılmayı seviyorum, böylece en azından güvenle söyleyebilirim ki: “Yıllarca kullanılmış ve kapsamlı testlerle güvence altına alınan bu küçük izole edilmiş kütüphane, kaotik dış dünyada neler olup bittiğine bakılmaksızın değişiklik gerektirme olasılığı neredeyse yok ." Dışarıda ne tür tasarım değişiklikleri yapılması gerektiğinden bağımsız olarak bana bir parça akıl sağlığı veriyor.

Kavrama ve Kararlılık, ECS Örneği

Varlık-bileşen sistemlerini de seviyorum ve çok sıkı bir bağlantı sağlıyorlar çünkü sistem bağımlılık bileşenlerini tümüyle erişiyor ve ham verilere doğrudan erişiyor, şöyle yapıyor:

görüntü tanımını buraya girin

Buradaki tüm bağımlılıklar oldukça dardır, çünkü bileşenler yalnızca ham verileri gösterir. Bağımlılıklar soyutlamalara doğru akmıyor, ham veriye doğru akıyorlar, bu da her sistemin erişmek istedikleri her bileşen türü hakkında mümkün olan en fazla bilgiye sahip olduğu anlamına geliyor. Bileşenlerin tüm verilere ham verilere erişen ve bunları kurcalayan işlevselliği yoktur. Bununla birlikte, böyle düz bir sistem olduğu için böyle bir sistem için mantıklı olmak çok kolaydır. Eğer bir doku berraklaşırsa, o zaman bu sistemle yalnızca işleme ve boyama sisteminin doku bileşenlerine eriştiğini bilirsiniz ve işleme sistemini yalnızca tek tek dokulardan kavramsal olarak okuduğu için hızlıca ekarte edebilirsiniz.

Bu arada, gevşek bir şekilde birleştirilmiş bir alternatif de şu olabilir:

görüntü tanımını buraya girin

... tüm bağımlılıkların veriye değil soyut fonksiyonlara doğru aktığı ve bu şemadaki her bir şeyin kendi aralarında ortak bir arayüz ve işlevsellik gösterdiği görüldü. Burada tüm bağımlılıklar çok gevşek olabilir. Nesneler doğrudan birbirlerine bile bağlı olmayabilir ve saf arayüzler aracılığıyla birbirleriyle etkileşime girmeyebilir. Yine de, özellikle karmaşık bir etkileşim karışıklığı göz önüne alındığında, bir şeyler ters giderse, bu sistem hakkında düşünmek çok zor. Ayrıca, ECS'den daha fazla etkileşim (daha fazla bağlantı olsa da, daha da fazla olsa da) da olacaktır, çünkü kurumlar, birbirlerinin soyut halka açık ara yüzünü bilseler bile, topladıkları bileşenler hakkında bilgi sahibi olmak zorundadır.

Ayrıca, herhangi bir şeyde tasarım değişiklikleri varsa, ECS'den daha fazla kademeli kırılma elde edersiniz ve tipik olarak tasarım değişiklikleri için her neden daha hoş bir nesne yönelimli bir arayüz ve soyutlama sağlamaya çalıştığından daha fazla neden ve cazibe olacaktır. Bu, hemen hemen her küçük şeyin, tasarıma kısıtlamalar ve sınırlamalar getirmeye çalışacağı fikriyle birlikte gelir ve bu kısıtlamalar, genellikle tasarımın değiştiği garantidir. İşlevsellik çok daha kısıtlıdır ve ham verilerden çok daha fazla tasarım varsayımı yapmak zorundadır.

Uygulamada, yukarıdaki "düz" ECS sisteminin tipinin, akıl almaz bağımlılıklara sahip karmaşık bir örümcek ağına sahip en gevşek bağlanmış sistemlerden bile daha kolay olduğunu buldum ve en önemlisi benim için çok az neden buldum. ECS sürümünün, mevcut bileşenlerin hiç değişmemesi gerektiğinden, bağlı olan bileşenlerin, sistemlerin çalışması için gerekli verileri sağlamaktan başka hiçbir sorumluluğu yoktur. IMotionDeğişmeyenleri özel veriler üzerinde tutmaya çalışırken, yalnızca sorunu çözmek için ilgili ham verileri sağlaması gereken ve hareket etmeyen bir hareket bileşenine karşı gelişmiş işlevselliği sağlayan bu arabirimi uygulayan saf bir arabirim ve somut hareket nesnesi tasarlamanın zorluğunu karşılaştırın işlevsellik.

İşlevsellik veriden daha doğru elde etmek için çok daha zor, bu yüzden bağımlılıkların verilere doğru akışını yönlendirmenin genellikle tercih edildiğini düşünüyorum. Sonuçta, kaç tane vektör / matris kütüphanesi var? Kaç tanesi aynı veri sunumunu kullanıyor ve sadece işlevsellikte çok farklı? Sayısız ve yine de aynı veri sunumlarına rağmen hala çok fazla şey var, çünkü işlevsellikte ince farklılıklar istiyoruz. Orada kaç resim kütüphanesi var? Kaç tanesi pikselleri farklı ve benzersiz bir şekilde temsil ediyor? Neredeyse hiç ve yine işlevselliğin birçok senaryoda verilere göre tasarım değişikliklerine karşı çok daha dengesiz ve eğilimli olduğunu göstermek. Elbette bir noktada işlevselliğe ihtiyacımız var, ancak bağımlılıkların büyük bir kısmının verilere doğru aktığı sistemleri tasarlayabilirsiniz, ve genel olarak soyutlamalar veya işlevsellik için değil. Bu, kuplaj üzerindeki stabiliteye öncelik veriliyor olacaktır.

Şimdiye kadar yazdığım en istikrarlı işlevler (80'lerin sonlarından beri onları değiştirmek zorunda kalmadan kullandığım ve yeniden kullandığım tür), yalnızca bir diziyi kabul eden bir geometri işlevi gibi ham verilere dayanan işlevlerdi. karmaşık bağlıdır mantarlar ve tamsayı, olanlar değil Meshnesne veya IMesharayüz ya da vektör / matris çarpım sadece bağlı olan float[]ya da double[]bağlı olmayan bir, FancyMatrixObjectWhichWillRequireDesignChangesNextYearAndDeprecateWhatWeUse.

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.