2016-07-10 19 views
6

Ich habe ein Problem mit der richtigen Vererbungskette, ohne dabei gute Teile des DRY-Prinzips zu verlieren.Zwei verschiedene Vererbungsketten ohne das DRY-Prinzip zu brechen

die folgende Struktur wiedergegeben:

  • abstrakte Klasse A ist meine Basis für alle Klassen
  • abstrakte Klasse B: Eine meine Basis für alle Klassen ist, die speziellen Eigenschaften (zur Verfügung gestellt durch B)
  • haben

Jetzt muss ich zwei neue Klassen haben, die die gleichen Funktionen teilen. Aber einer ist vom Typ A, während der andere vom Typ B ist. (Dies kann nicht geändert werden!) Beide Klassen sollten eine Methode SetSize() haben.

Also wäre am Ende Klasse C: A und D: B, beide hätten die gleiche SetSize-Methode.

Frage: Wie würde ich eine Basisklasse, Zwischenschicht erstellen, damit die SetSize() -Methode nur einmal (DRY) deklariert/implementiert wird? Ich denke etwas über die Verwendung von Schnittstellen oder einige statische Helfer-Klassen, um die Logik von SetSize() zu implementieren?

Gibt es Muster oder Best Practices, um dieses Verhalten zu erreichen?

+2

Related - [Bevor Vererbung über Vererbung] (http://stackoverflow.com/questions/49002/prefer-composition-over-heritance) –

+0

Ist das Verhalten von 'SetSize' für alle Implementierungen identisch? (beide für Klassen vom Typ A und B, wie Sie "trocken" erwähnt haben)? – Yogi

+0

@Yogi Die Methode ist für beide Implementierungen identisch. Deshalb suche ich nach einem Weg, um es an einem einzigen Punkt zu haben – KingKerosin

Antwort

2

Sie können dies nicht über die Vererbung in C# tun, da die Mehrfachvererbung nicht unterstützt wird. das Werkzeug der Sprache, die Sie für dieses Szenario gibt Schnittstellen:

public interface 
{  
    void SetSize(Size size); 
} 

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

auch verwendet werden, dass Vererbung bedenken sollten, wenn die Typen in der Vererbungskette haben eine eine Beziehung (a Cat ist ein Animal, ein B ist ein A, usw.), während Schnittstellen bevorzugt sind, wenn völlig nicht verwandte Klassen ein sehr spezifisches gemeinsames Verhalten haben; IEquatable, IComparable, IDisposable, usw. Ihr SetSize Verhalten scheint in dieser letzten Kategorie besser zu passen, da es keine spezifische Funktionalität für A oder B zu sein scheint.

Wenn nun beide SizableA und SizableB sollten die gleiche Umsetzung SetSize dann die beste Lösung teilen ist Zusammensetzung zu verwenden oder einfach delegieren Funktionalität:

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

eine abstrakte Klasse Stellen umfassen SetSize() -Methode und gemeinsame Eigenschaften der A- und B-Klassen. Dann erben A- und B-Klassen die abstrakte Klasse.

Verwandte Themen