2010-02-04 14 views
13

Sorry, wenn das klingt einfach, aber ich bin auf der Suche nach etwas Hilfe mein Code zu verbessern :)Refactoring abstrakte Klasse in C#

Also zur Zeit habe ich die folgende Implementierung (die ich schrieb auch):

public interface IOptimizer 
{ 
    void Optimize(); 
    string OptimizerName { get; } 
} 

public abstract AbstractOptimizer : IOptimizer 
{ 
    public void Optimize() 
    { 
     // General implementation here with few calls to abstract methods 
    } 
} 

public abstract AbstractPriorityOptimizer : AbstractOptimizer 
{ 
    // Optimize according to priority criteria.  

    string Name 
    { 
     get { return "Priority Optimizer"; } 
    }  
} 

Dann hat ich technologiespezifische konkrete Klassen:

TechnologyXPriorityOptimizer : AbstractPriorityOptimizer 
TechnologyYPriorityOptimizer : AbstractPriorityOptimizer 


Jetzt versuche ich, ein generisches Optimierungsprogramm an, eine, die für optimiert andere Bedingungen als Priorität, so dass mein Versuch:

public abstract AbstractGenericOptimizer : AbstractOptimizer 
{ 
    // Optimize according to a generic criteria.  

    private readonly int param; 

    public AbstractGenericOptimizer (int param) : base() 
    { 
      // param affects the optimization 
      this.param = param; 
    }   
} 

und ich brauche auch technologiespezifische Umsetzung ebenso wie die Priorität Optimierer:

TechnologyXGenericOptimizer : AbstractGenericOptimizer 
TechnologyYGenericOptimizer : AbstractGenericOptimizer 


Q1. TechnologyXPriorityOptimizer und TechnologyXGenericOptimizer haben die gleichen genauen "extra" Methoden, weil sie die gleiche Technologie beinhalten. Gibt es eine Möglichkeit, diese Methode für beide Vererbungszweige gemeinsam zu verwenden?

Q2. Für AbstractGenericOptimizer, der Optimierer hat einen speziellen Namen für spezielle Werte des int param, so wäre es eine gute Idee, die Basis generische Optimierer Klasse zu erweitern (wo param ist hardcoded) und dann für jede Abteilung, eine Technologie-spezifische Implementierung:

AbstractSpecialName1Optimizer: AbstractGenericOptimizer 
TechnologyXSpecialName1Optimizer: AbstractSpecialName1Optimizer 
TechnologyYSpecialName1Optimizer: AbstractSpecialName1Optimizer 

AbstractSpecialName2Optimizer: AbstractGenericOptimizer 
.... 

Was wäre der beste Weg, dieses Szenario zu refaktorieren? Ich glaube, dass es eine klügere Möglichkeit gibt, die Anzahl der Vererbungsebenen zu reduzieren.

Danke!

Antwort

8

Sie sollten wahrscheinlich Containment statt Vererbung verwenden.

Zum Beispiel könnte man eine abstrakte OptimizerStrategy Klasse mit konkreten Implementierungen für jede Technologie machen, dann macht die GenericOptimizer und PriorityOptimizer ein OptimizerStrategy als generisches Typargument nehmen oder Konstruktorparameter.

+0

Vielen Dank für Ihren Vorschlag. In diesem Fall implementiere ich Optimize() in der OptimizerStrategy-Klasse? Was soll ich mit IOptimizer machen? – alhazen

+0

Ich habe keine Ahnung; Es hängt davon ab, was der Code tatsächlich tut. Wahrscheinlich jedoch beides. – SLaks

3

Ad hoc Ich neige dazu zu sagen, dass Sie Ihr gewünschtes Design nicht nur durch Vererbung erhalten können. Sie müssen orthogonale Vererbungswege haben - Priorität und generische auf der einen Seite und Technologie X und Y auf der anderen Seite. Sie möchten Code aus beiden Pfaden in den möglichen vier Kombinationen kombinieren, aber dies würde mehrfache Vererbung erfordern - erben von Priorität oder generisch und Technologie X oder Y. Weil C# keine Mehrfachvererbung unterstützt, wird dies nicht funktionieren.

Ich würde versuchen, dies zu lösen, indem Sie Schnittstellen und strategy pattern verwenden. Dies sollte es Ihnen ermöglichen, den für alle vier Kernkomponenten spezifischen Code in separate Klassen zu extrahieren und dann immer zwei von ihnen in jeder der vier gewünschten Kombinationen zusammenzuführen.

+0

Danke für den Link – alhazen