Расположение зависимостей (стратегии, репозитории и т. Д.) В зависимости от типа подкласса - PullRequest
1 голос
/ 06 апреля 2011

Представьте, что у меня есть следующая структура наследования:

AnimalsNamespace.Animal
CatsNamespace.Cat : Animal
DogsNamespace.Dog : Animal

В моих классах приложений я часто сталкиваюсь со следующим типом кода:

void Feed(Animal animal)
{
    if (animal is Cat)
    {
         KernelContainer.Get<ICatFeedingStrategy>().Feed((Cat)animal);
    }
    else if (animal is Dog)
    {
         KernelContainer.Get<IDogFeedingStrategy>().Feed((Dog)animal);
    }
}

Это нормально какое-то время, но после того, как у меня есть куча этих утверждений, лежащих вокруг. Затем я также начинаю получать проблемы с прокси-серверами NHibernate, которые ведут себя странно, когда вы запрашиваете их тип и т. Д., И все в порядке.

Я мог бы создать класс Factory, но в итоге я получил целую кучу сложностей, так как мне просто нужно кормить кошку: ICatFeedingStrategy, ConcreteCatFeedingStrategy, IAnimalFeedingStrategyFactory, ConcreteAnimalFeedingStrategyFactory ... (плюс часто абстрактный базовый класс, такой как AnimalFeedingStrategyBase).

Существует ли шаблон, который может помочь более эффективно управлять этими структурами наследования?

Ответы [ 2 ]

0 голосов
/ 07 апреля 2011

Может быть, цепь ответственности может помочь здесь. Во-первых, каждый «фидер» регистрируется в цепочке. Затем feed() вызывает первого «фидера» из цепочки. Каждый фидер знает, как прокормить свой собственный подкласс. Тем не менее, у вас есть много if -ов, но они тесно связаны со своими подклассами.

0 голосов
/ 06 апреля 2011

Прямо сейчас вы программируете для конкретных классов, где вы действительно должны программировать для интерфейсов .

Пример выше может быть решен с помощью с использованием Abstract Factory для разрешения зависимостей на основе информации времени выполнения . Теперь метод Feed может выглядеть так:

void Feed(Animal animal)
{
    var strategy = this.factory.GetFeedingStrategy(animal);
    strategy.Feed(animal);
}

Где factory - это введенный IFeedingStrategyFactory.

Другой вариант, когда у вас есть конечный список известных подтипов, это использовать Шаблон посетителя .

...