Alt sınıflandırma neden çok kötü (ve bu yüzden bunu ortadan kaldırmak için prototipleri neden kullanmalıyız)?


10

Tasarım desenlerini okuyordum ve prototip tasarım deseninin aşırı alt sınıflama ile ortadan kalktığını okudum.

Alt sınıflandırma neden kötü? Bir prototip kullanmanın aşırı alt sınıflamaya ne faydası olur?


kim söylüyor ? bağlantın var mı
camus

Bu kitabın 188'ini okuyordum. goo.gl/6JGw1
David Faux

Yanıtlar:


19

Alt sınıflandırma neden çok kötü

"Çok fazla" bir yargılama çağrısıdır; ama benden al kötü. Birlikte çalıştığım kodun DEEP mirası var ve kodu okumak, anlamak, takip etmek, izlemek, hata ayıklamak vb.Gibi çok zordur.

Prototip deseni alt sınıflamayı ortadan kaldırır

Yoksa soru "çok fazla alt sınıftan uzaklaşıyor mu?" Bu desen, en azından bu noktada, alt sınıflamayı önlemek için bir "şablon" nesnesini klonlamayı gerektirir. "Şablon" un bir alt sınıf olamayacağını söyleyen bir kural yoktur.

Kompozisyonun miras yerine tercih edilmesi

Buradaki fikir aynı zamanda temsilci seçme ve toplama da içerir. Bu sezgisel yöntemi takip etmek , yazılımınızın daha esnek, bakımı kolay, genişletme ve yeniden kullanma eğiliminde olduğu anlamına gelir .

Bir sınıf parçalardan oluştuğunda , çalışma zamanında bu parçaları değiştirebilirsiniz . Bunun test edilebilirlik üzerinde derin bir etkisi vardır.

Test yapmak daha kolaydır . Sahte parçalar kullanabilirsiniz (örn. "Alay", "çiftler" ve diğer test konuşmaları). Kodumuzun derin mirası, herhangi bir parçasını test etmek için tüm hiyerarşiyi başlatmamız gerektiği anlamına gelir. Bizim durumumuzda bu kodu gerçek ortamında çalıştırmadan mümkün değildir. Örneğin, iş nesnelerini somutlaştırmak için bir veritabanına ihtiyacımız var.

Değişiklikler yan etkiler ve belirsizlikle birlikte gelir - Sınıf ne kadar "temel" olursa, iyi ya da kötü için etkileri o kadar yaygın olur. Yan etkiler belirsizliğinden dolayı yapmaya cesaret edemeyeceğiniz değişiklikler olabilir. Ya da miras zincirimizdeki bir yer için iyi olan bir değişiklik diğeri için kötüdür. Bu kesinlikle benim deneyimim.


Kalıtımın testi (özellikle alaycılığı) ne zaman zorlaştırdığına ve kompozisyonun buna nasıl yardımcı olduğuna dair bazı örnekler görmek gerçekten ilgimi çekiyor.
Armand

@alison: Türetilmiş bir sınıftaki, taban sınıftaki uygulamanın, temel sınıftaki uygulamanın hata senaryolarını sınamayı neredeyse imkansız kıldığı bir yöntem kullanan bir yöntem. Bu kompozisyon olsaydı, hatanın ortaya çıkmasına neden olan bir nesneyi enjekte etmek daha kolay olurdu
Rune FS

@allison: Örnekler? Kod tabanı çok büyük olduğunda, temel sınıflar düzinelerce sınıf tarafından doğrudan ve yüzlerce miras tarafından kullanıldığında. Derin kalıtım noktası yeniden kullanıldığından ve böylece bir temel sınıf, hata ayıklayıcı yığın izlemesinin gerçekte hangi yöntemlerin çağrıldığını gösteremediği noktaya genelleştirilir. Son olarak, böyle bir Frankenstein içine zaten bağımlılık enjeksiyonu olmadığında. Üst düzey bir sınıf, her biri kendi miras eğlence evine sahip düzinelerce iç nesneye topluca "sahip" yarım düzine veya daha fazla şey olabilir.
radarbob

8

Bunun kötü bir uygulama olarak görülmesinin nedenlerinden biri, zaman içinde her alt sınıfın, bu nesne için hiçbir anlam ifade etmeyen özellikler ve yöntemler içerebileceğidir (daha az gelişmiş bir hiyerarşide). Sonunda, söz konusu sınıf için anlamlı olmayan öğeler içeren şişirilmiş bir sınıfla karşılaşabilirsiniz.

Ben kendim bu konuda agnostikim. Sadece kötü olduğunu söylemek dogmatik görünüyor. Yanlış kullanıldığında her şey kötü.


2

İki sebep.

  1. Çalışma zamanı performansı. Bir üst sınıftan bir alt sınıfı çağırdığınızda, bir yöntem çağrısı yapıyorsunuzdur, bu yüzden beş sınıfı iç içe yerleştirdiyseniz ve temel sınıfta bir yöntemi çağırdıysanız, beş yöntem çağrısı yaparsınız. Çoğu derleyici / çalışma zamanı bunu tanımaya ve ekstra çağrıları optimize etmeye çalışacaktır, ancak bunu sadece çok basit durumlarda yapmak güvenlidir.

  2. Programcılarınızın akıl sağlığı. Eğer beş sınıfta yuva yaparsanız, temel sınıfta gerçekten bir yöntem çağırdığınızı belirlemek için dört ana sınıfı da incelemeliyim. Programda hata ayıkladığımda beş yöntem çağrısında da adım atmam gerekebilir.


6
-1: # 2 hakkında haklısın; ama yaklaşık # 1 değil. Kalıtım birkaç kat olmaz zorunlu çalışma zamanı performansını etkileyebilir.
Jim

Makine kodu düzeyinde ve OP ve miras kullanarak birkaç ekstra prosedür çağrısından endişeleniyorsunuz ve diğer programcılarınızın akıl sağlığı hakkında endişeleniyorsunuz .....
mattnz

@JimG. Değil, ama olabilir. :) Ayrıca, endişelenmeniz gereken bellek kullanımı da vardır: tabanın tüm değişkenlerini yeniden kullanmazsanız, yine de nesneyi oluşturmanın bir parçası olarak tahsis edilebilirler.
Adam Lear

2

"Çok fazla" bir yargılama çağrısıdır.

Programlamadaki çoğu şeyde olduğu gibi, alt sınıflandırma mantıklı olduğunda doğal olarak kötü değildir . Sorun çözümünüzün modeli, bir parça bileşiminden ziyade bir hiyerarşi olarak daha anlamlı olduğunda, alt sınıflandırma tercih edilen seçenek olabilir.

Bununla birlikte, kompozisyonu miras yerine tercih etmek iyi bir kural.

Eğer alt sınıf, test daha zor olabilir ( radarbob belirtildiği gibi ). Derin bir hiyerarşide, sorunlu kodu izole etmek daha zordur çünkü bir alt sınıfı başlatmak için tüm üst sınıf hiyerarşisini ve bir dizi ek kodu getirmeniz gerekir. Kompozisyonel bir yaklaşımla, toplu nesnenizin her bileşenini birim testleri, sahte nesneler vb. İle izole edebilir ve test edebilirsiniz.

Alt sınıflandırma, uygulamanızın istemeyebileceğiniz ayrıntılarını göstermenize de neden olabilir. Bu, verilerinizin temel temsiline erişimi kontrol etmeyi zorlaştırır ve sizi destek modelinizin belirli bir uygulamasına bağlar.

Düşünebileceğim bir örnek Hashtable'dan miras kalan java.util.Properties. Properties sınıfının yalnızca String-String çiftlerini depolaması amaçlanmıştır (bu Javadoc'larda belirtilmiştir). Kalıtım nedeniyle, Hashtable'ın put ve putAll yöntemleri Properties kullanıcılarına maruz bırakılmıştır. Bir özelliği saklamanın "doğru" yolu setProperty () ile olsa da, bir kullanıcının put () çağrısı yapmasını ve bir String ve Object iletmesini engelleyen kesinlikle hiçbir şey yoktur.

Temel olarak, Özelliklerin semantiği kalıtımdan dolayı kötü tanımlanmıştır. Ayrıca, herhangi biri Özellikler için yedekleme nesnesini değiştirmek isterse, etkinin Özellikler kullanan kod üzerinde, Özellikler'in daha kompozisyonlu bir yaklaşım benimsemesinden çok daha büyük bir etkisi olacaktır.


2

Kalıtım bazı durumlarda kapsüllemeyi kırabilir ve bu olursa kötüdür. Daha fazlası için okuyun.


Kalıtım olmadan eski güzel günlerde, bir kütüphane, bir API ve uygulamayı kullanarak herkese açık olanı kullanır ve kütüphanenin artık Uygulamayı bozmadan değişmeye devam eden iç dişlileri ele almanın kendi yolu vardır.

İhtiyaçlar geliştikçe kütüphane gelişebilir ve daha fazla müşteriye sahip olabilir; veya kendi sınıfından diğer lezzetlerle miras olarak genişletilmiş işlevsellik sağlayabilir. Çok uzak çok iyi.

Bununla birlikte, temel şey, bir uygulama sınıfı ele geçirir ve alt sınıflamaya başlarsa, şimdi bir alt sınıf aslında bir iç ortaktan ziyade bir istemcidir . Ancak, genel API'nin tanımlandığı açık ve net bir yoldan farklı olarak, alt sınıf artık kitaplığın içinde çok daha derindir (tüm özel değişkenlere erişim vb.). Henüz kötü değil, ama kötü bir karakter APP içinde ve kütüphanede çok fazla olan bir API'yi köprüleyebilir.

Aslında bu her zaman böyle olmayabilir ama,

Kapsüllemeyi kırmak için kalıtımı yanlış kullanmak kolaydır

Bu noktada alt sınıfa izin vermek yanlış olabilir.


1

Kısa Hızlı Yanıt:

Bu ne yaptığınıza bağlıdır.

Genişletilmiş Sıkıcı Cevap:

Bir geliştirici bir uygulama yapabilir. alt sınıflandırma veya (prototippal) şablonları kullanarak. Bazen bir teknik daha iyi sonuç verir. Bazen diğer teknik daha iyi çalışır.

Teknikle seçim yapmak en iyi sonucu verir, aynı zamanda bir "Çoklu Kalıtım" senaryosunun mevcut olup olmadığını da dikkate almak gerekir. Programlama dili yalnızca tek miras, şablonlar veya prototipleri desteklese bile.

Tamamlayıcı Not:

Bazı cevaplar "çoklu kalıtım" ile ilgilidir. Altought, ana soru değil, konuyla ilgili. "Çoklu kalıtım ve kompozisyon" hakkında birkaç benzer mesaj vardır. İkisini de karıştırdığım bir vakam vardı.

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.