Miras ne zaman kullanılır, 'sadece bir boole alanı' ne zaman kullanılır?


18

Rails uygulamamızda bildirim ekliyoruz. Bunlardan bazıları blocking: Eklendikleri kaynakların ilerlemesini durdururlar, çünkü bu kaynakla ilgili bazı bilgiler eksiktir.

Diğer bildirimler basit bildirimlerdir ve yalnızca bilgi sağlar.

Bugün ekibimizdeki başka bir programcıyla görüştüm. Kalıtım yapısını şöyle yarattım:

resim açıklamasını buraya girin

Bununla birlikte, blockingher bir Bildirime yalnızca bir boole döndürme yöntemi olarak eklememi ve Bildirim üst sınıfında engellenen alt sınıfların bir listesini belirtmemi tercih ediyor.

Bu yaklaşımlar arasındaki fark çok büyük değildir; benim yaklaşımımda kök sınıfı temiz tutarak bu listeyi belirtmek zorunda değilim. Öte yandan, Notification::Blockingşu anda gerçekleşen özel mantık da çok büyük değil.

Bu sorun için ne tür bir soyutlama daha uygundur?


11
Bir ebeveyn sınıfı onun çocukları hakkında asla bilmemelidir. Neden alt sınıfların bir listesini tutmanız gerekiyor?
coteyr

Bir kaynağa nasıl eklenirler ve ilerlemelerini nasıl durdururlar?
boş

3
Neden bu kadar çok bildirim sınıfına ihtiyacınız var? Bana bir bildirim sınıfı oluşturabileceğiniz gibi geliyor, ardından verilerin veri türleri yerine eylemleri gerçekleştirmesine izin verin.
16:29

1
@Trisped: doğru, eğer davranışın bir yönünü kapsamlı bir vaka listesi ile temel sınıfa taşırken, inançlarınızın cesaretine sahip olun, uzantıyla özelleştirme için gerçekten kullanılabilir bir temel sınıf tasarlamadığınızı itiraf edin ve tüm davranışı temel sınıfa taşıyın !
Steve Jessop

Yanıtlar:


35

Temel sınıflardan türetilmiş sınıfları bilmek istemezsiniz. Sıkı bağlantıyı tanıtır ve bir bakım baş ağrısıdır, çünkü her yeni türetilmiş sınıf oluşturduğunuzda listeye eklemeyi hatırlamanız gerekir.

Ayrıca, bu sınıfı birden çok projede kullanmak istiyorsanız, Notification sınıfını yeniden kullanılabilir bir pakete / derlemeye yerleştirebilmenizi de engeller.

Gerçekten tek bir temel sınıf kullanmak istiyorsanız, bunu çözmenin başka bir yolu, temel Bildirim sınıfına bir sanal özellik veya yöntem IsBlocking eklemektir. Türetilmiş sınıflar daha sonra true veya false döndürmek için bunu geçersiz kılabilir. Temel sınıf türetilmiş sınıfları bilmeden tek bir sınıf çözümünüz olur.


3
Bu. Kararları tek bir yerde alın. Sınıf ve liste arasında hangi sınıfların engellendiğine dair bilgi dağıtmayın.
candied_orange

Bu benim yaptığım, çok iyi çalışıyor ve çok tekrar kullanılabilir.
coteyr

13

ve Bildirim üst sınıfında engellenen alt sınıfların bir listesini belirtin.

Bu çok tuhaf görünüyor ve belirli bir kod kokusu.

Sınıflar arasında davranış farklılıklarınız varsa ve tüm bu bildirimleri aynı şekilde (yani polimorfizm kullanarak ) ele almak istiyorsanız, alt sınıflar sağlarım .


1
Bence "davranış" burada anahtar: sadece veri olduğunda, alan yeterli bir ayrımcı olmalıdır. Davranış polimorfizm kullanmak için daha iyi bir nedendir, ancak kalıtım hiyerarşileri oluştururken her zaman bakım karmaşıklığını göz önünde bulundurmak gerekir. Okuma en.wikipedia.org/wiki/Composition_over_inheritance
cottsak

7

Mevcut cevapların bir tersi olarak, kullanılacak modun dinamik olarak değiştirilmesi gerekiyorsa (örneğin, hangi türlerin engelleneceğini listeleyen bir yapılandırma dosyası aracılığıyla) boolean özelliğinin en iyi seçenek olduğunu öneririm ve hangileri değil).

Bununla birlikte, bu durumda bile daha iyi bir tasarım bir Decorator nesnesi kullanmak olabilir.


1

İlk düşüncem "ikisi de" ile gitmek olsa da, bir engelleme bildirimi hakkında başka ne kadar özel bağlı olduğunu söyleyebilirim:

class Notification
 virtual Boolean Blocking{get return false;}

class BlockingNotification inherits Notification
 virtual overrides Boolean Blocking{get return true;}

Bu şekilde n.Blockingveya n is BlockingNotification(tümünü sahte kodda) kullanabilirsiniz, ancak bir sınıfın bağlama duyarlı bir Blockingdeğer uygulamasına izin verirseniz, bu değeri her seferinde kontrol etmek zorunda kalacağınızı görürseniz, BlockingNotificationsınıf daha az kullanışlı.

Her durumda, temel sınıf uygulamasının Blockingtüretilmiş sınıflar hakkında bilgi sahibi olmasını istemediğiniz diğer cevaplara katılıyorum .


0

İki temel sınıf ve her birinin birden çok örneğini yapmak yerine, bildirimin engellenip engellenmediğini ve bildirimi kullanıcıya iletmek için gereken diğer bilgileri belirtmek için bir bool içeren bir bildirim sınıfı yapın.

Bu, bildirimleri işlemek ve sunmak için bir kod kümesi kullanmanıza olanak tanır ve kodunuzun karmaşıklığını azaltır.

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.