2016-07-10 12 views
6

Mam problem z korzystaniem z właściwego łańcucha dziedziczenia bez utraty dobrych części zasady DRY.Dwa różne łańcuchy dziedziczenia bez łamania zasady DRY

Biorąc pod uwagę następującą strukturę:

  • abstrakcyjna klasa A jest moja baza dla wszystkich klas
  • abstrakcyjna klasa B: A jest moja baza dla wszystkich klas, które mogą mieć szczególne cechy (udostępnione przez B)

Teraz muszę mieć dwie nowe klasy, które mają te same funkcje. Ale jeden jest typu A, a drugi jest typu B. (Nie można tego zmienić!) Obie klasy powinny mieć metodę SetSize().

Tak więc na końcu będzie klasa C: A i D: B, obie mają tę samą metodę SetSize.

Pytanie: W jaki sposób utworzyć warstwę pośrednią, warstwę pośrednią, aby uzyskać SetSize() -metodę zadeklarowaną/zaimplementowaną tylko raz (DRY)? Chyba coś o użyciu interfejsów lub niektórych statycznych klas pomocniczych do wdrożenia logiki SetSize()?

Czy istnieją jakieś wzorce lub najlepsze praktyki, aby osiągnąć to zachowanie?

+2

Powiązane - [Preferuj kompozycję nad dziedziczeniem] (http://stackoverflow.com/questions/49002/prefer-composition-over-initance) –

+0

Czy zachowanie "SetSize" będzie takie samo dla wszystkich implementacji? (zarówno dla klas typu A i B, jak wspomniałeś 'sucho')? – Yogi

+0

@Yogi Metoda będzie dokładnie taka sama dla obu implementacji. To dlatego szukam sposobu, aby mieć go w jednym punkcie – KingKerosin

Odpowiedz

2

Nie można tego zrobić poprzez dziedziczenie w języku C#, ponieważ nie obsługuje dziedziczenia wielokrotnego; narzędzie język daje dla tego scenariusza jest interfejsy:

public interface 
{  
    void SetSize(Size size); 
} 

public SizableA: A, ISizable { ... } 
public SizableB: B, ISizable { ... } 

Również pamiętać, że dziedziczenie powinien być stosowany, gdy typy w łańcuchu dziedziczenia mają jest relacją (a Cat jest Animal, A B to A itp.), Podczas gdy interfejsy są preferowane, gdy całkowicie niepowiązane klasy mają bardzo specyficzne, typowe zachowanie; IEquatable,, , itp. Twoje zachowanie SetSize wydaje się pasować lepiej w tej ostatniej kategorii, ponieważ nie wydaje się być funkcjonalnością specyficzną dla A lub B.

Teraz, gdy oba SizableA i SizableB powinny dzielić tę samą realizację SetSize to najlepszym rozwiązaniem jest użycie kompozycji lub po prostu przekazać funkcjonalność:

public interface ISizable 
{ 
    void SetSize(Size size, ISetSizeProvider provider); //Alternatively inject provider in SizableA and SizableB's constructor to get composition. 
} 
0

Złóż klasa abstrakcyjna obejmują setSize() metody i wspólne właściwości klas A i B. Następnie klasy A i B dziedziczą klasę abstrakcyjną.

Powiązane problemy