Почему Abstract Factory использует абстрактный класс вместо интерфейса?

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

В книге фабричный класс реализован так:

public abstract class AbstractVehicleFactory
{
    public abstract IBody CreateBody();
    public abstract IChassis CreateChassis();
    public abstract IGlassware CreateGlassware();
}

После выполнения упражнения я заметил, что приведенный выше класс можно заменить этим кодом:

public interface IAbstractVehicleFactory
{
      IBody CreateBody();
      IChassis CreateChassis();
      IGlassware CreateGlassware();
}

Конечно, оба примера работают одинаково, но интересно, в чем причина использования абстрактного класса, а не интерфейса?


person user1615362    schedule 17.09.2013    source источник


Ответы (4)


Абстрактный класс можно с осторожностью расширять ненарушающим образом; все изменения в интерфейсе являются критическими изменениями.

Обновление:
Напротив, интерфейс может быть параметром типа in или out, а абстрактный класс — нет. Иногда то или другое больше подходит для данного дизайна, а иногда это жеребьевка.

person Pieter Geerkens    schedule 17.09.2013

"Abstract" в "abstract factory" не имеет ничего общего с "abstract" в abstract class. Абстрактная фабрика является «базой» для конкретной фабрики, но сам шаблон проектирования не требует какой-либо конкретной реализации. Абстрактная фабрика может быть абстрактным или даже конкретным классом, интерфейсом или какой-либо формой типа утиного объекта в зависимости от используемого вами языка.

Действительно, в C# interface — очень разумный способ указать абстрактную фабрику.

person Alexei Levenkov    schedule 17.09.2013

Интерфейс действительно является самым элегантным способом сделать это.

Аргумент для использования абстрактного класса: иногда может быть полезно использовать абстрактный класс, когда класс поддерживает состояние, а некоторые части уже известны.

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

person Willem Van Onsem    schedule 17.09.2013
comment
Но если я использую интерфейс, не нарушает ли это исходный шаблон проектирования? У меня сложилось впечатление, что смысл использования DP заключается в поддержании согласованности. - person user1615362; 17.09.2013
comment
Насколько я знаю, нет. В таких языках, как C++, где разрешено множественное наследование, можно утверждать, что интерфейсов не существует. Шаблоны проектирования — это просто рекомендации по структурированию кода. В них нет формального описания, должны ли вы использовать интерфейсы или абстрактные классы, должны ли поля быть закрытыми или общедоступными... - person Willem Van Onsem; 17.09.2013

Вероятно, это опечатка в книге, и первый «интерфейс» на самом деле был абстрактным классом.

Нет такого понятия, как «абстрактный интерфейс». Интерфейс по определению абстрактен.

person aleciten    schedule 17.09.2013
comment
Право, моя вина! Я перепутал класс/интерфейс при создании этого вопроса. - person user1615362; 17.09.2013