2010-02-04 29 views
13

Lo siento si esto suena simple, pero estoy buscando un poco de ayuda para mejorar mi código :)clase abstracta Refactoring en C#

Así que disponemos de la siguiente aplicación (que también he escrito):

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"; } 
    }  
} 

entonces tengo clases concretas de la tecnología:

TechnologyXPriorityOptimizer : AbstractPriorityOptimizer 
TechnologyYPriorityOptimizer : AbstractPriorityOptimizer 


Ahora estoy tratando de añadir un optimizador genérico, que optimiza para condiciones que no sean la prioridad, por lo que mi intento:

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; 
    }   
} 

y también necesito aplicación específica de la tecnología al igual que el optimizador de prioridad:

TechnologyXGenericOptimizer : AbstractGenericOptimizer 
TechnologyYGenericOptimizer : AbstractGenericOptimizer 


Q1. TechnologyXPriorityOptimizer y TechnologyXGenericOptimizer tienen los mismos métodos "extra" exactos porque implican la misma tecnología. ¿Hay alguna manera de mantener este método en común con ambas ramas de herencia?

Q2. Para AbstractGenericOptimizer, el optimizador tiene un nombre especial para valores especiales de int param, por lo que sería una buena idea ampliar la clase de optimizador genérico base (donde param está codificado) y luego para cada división, tener una implementación específica de tecnología:

AbstractSpecialName1Optimizer: AbstractGenericOptimizer 
TechnologyXSpecialName1Optimizer: AbstractSpecialName1Optimizer 
TechnologyYSpecialName1Optimizer: AbstractSpecialName1Optimizer 

AbstractSpecialName2Optimizer: AbstractGenericOptimizer 
.... 

¿Cuál sería la mejor manera de refactorizar este escenario? Siento que hay una forma más inteligente de reducir el número de niveles de herencia.

Gracias!

Respuesta

8

Probablemente deberías usar la contención en lugar de la herencia.

Por ejemplo, usted podría hacer una clase abstracta OptimizerStrategy con implementaciones concretas para cada tecnología, a continuación, hacer que el GenericOptimizer y PriorityOptimizer tomar una OptimizerStrategy como un argumento de tipo genérico o parámetro constructor.

+0

Gracias por su sugerencia. En este caso, ¿implemento Optimize() en la clase OptimizerStrategy? ¿Qué debería hacer con IOptimizer? – alhazen

+0

No tengo idea; depende de lo que el código realmente hace. Sin embargo, probablemente ambos. – SLaks

3

Ad hoc Tiendo a decir que no se puede obtener el diseño deseado utilizando solo herencia. Debe tener rutas de herencia ortogonales: prioridad y genérico por un lado y tecnología X e Y por el otro. Desea combinar el código de ambas rutas en las posibles cuatro combinaciones, pero esto requeriría herencia múltiple: heredaría de prioridad o genérico y tecnología X o Y. Como C# no es compatible con herencia múltiple, esto no funcionará.

Intentaré resolver esto usando interfaces y el strategy pattern. Esto debería permitirle extraer el código específico de los cuatro componentes principales en clases separadas y luego fusionar siempre dos de ellos en cada una de las cuatro combinaciones deseadas.

+0

Gracias por el enlace – alhazen