Рефакторинг абстрактного класса в C # - PullRequest
13 голосов
/ 04 февраля 2010

Извините, если это звучит просто, но я ищу некоторую помощь для улучшения моего кода:)

Итак, в настоящее время у меня есть следующая реализация (которую я также написал):

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

Затем у меня есть конкретные классы для конкретных технологий:

TechnologyXPriorityOptimizer : AbstractPriorityOptimizer 
TechnologyYPriorityOptimizer : AbstractPriorityOptimizer 


Теперь я пытаюсь добавить универсальный оптимизатор, который оптимизирует для условий, отличных от приоритета, поэтому моя попытка:

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

и мне также нужна реализация, специфичная для технологии, как оптимизатор приоритетов:

TechnologyXGenericOptimizer : AbstractGenericOptimizer 
TechnologyYGenericOptimizer : AbstractGenericOptimizer 


Q1.TechnologyXPriorityOptimizer и TechnologyXGenericOptimizer имеют одни и те же "дополнительные" методы, потому что они используют одну и ту же технологию.Есть ли способ сохранить этот метод общим для обеих ветвей наследования?

Q2.Для AbstractGenericOptimizer оптимизатор имеет специальное имя для специальных значений типа int param, поэтому было бы неплохо расширить базовый универсальный класс оптимизатора (где параметр жестко задан), а затем для каждого подразделения использовать технологию-специфичная реализация:

AbstractSpecialName1Optimizer: AbstractGenericOptimizer
TechnologyXSpecialName1Optimizer: AbstractSpecialName1Optimizer
TechnologyYSpecialName1Optimizer: AbstractSpecialName1Optimizer

AbstractSpecialName2Optimizer: AbstractGenericOptimizer
....

Как лучше всего реорганизовать этот сценарий?Я чувствую, что есть более разумный способ уменьшить количество уровней наследования.

Спасибо!

Ответы [ 2 ]

8 голосов
/ 04 февраля 2010

Вам, вероятно, следует использовать сдерживание вместо наследования.

Например, вы можете создать абстрактный класс OptimizerStrategy с конкретными реализациями для каждой технологии, а затем заставить GenericOptimizer и PriorityOptimizer принять OptimizerStrategy в качестве аргумента универсального типа или параметра конструктора.

3 голосов
/ 04 февраля 2010

Специально. Я склонен сказать, что вы не можете получить желаемый дизайн, используя только наследование. Вы должны ортогональные пути наследования - приоритет и общие с одной стороны и технологии X и Y с другой. Вы хотите объединить код из обоих путей в возможные четыре комбинации, но для этого потребуется множественное наследование - наследование от приоритета или универсального и технологии X или Y. Поскольку C # не поддерживает множественное наследование, это не будет работать.

Я бы попытался решить эту проблему, используя интерфейсы и шаблон стратегии . Это должно позволить вам извлечь код, характерный для всех четырех основных компонентов, в отдельные классы, а затем всегда объединять два из них в каждой из четырех требуемых комбинаций.

...