В чем разница между фабричным шаблоном и абстрактной фабрикой?


40

Наконец, серьезно начав пытаться выучить некоторые базовые паттерны (очень поздно в карьере, но это уже другая история), я пытаюсь разобраться в различиях между Фабричным паттерном и Абстрактной Фабрикой.

Каковы основные различия между этими двумя моделями?

Я понимаю, что Фабричный метод создает объекты с помощью наследования, а Абстрактная Фабрика делает это с помощью композиции объектов, но с практической точки зрения у меня все еще возникают проблемы с визуализацией, как именно они работают.



2
Чтобы уточнить, вы имеете в виду «фабричный метод», когда говорите «фабричный шаблон»? Если вы говорите о паттернах «Банды четырех», то здесь нет Фабричного паттерна, но есть Абстрактный Фабричный и Фабричный Метод.
Томас Оуэнс

Да, заводской метод.
Фил Уилер

3
Чтобы быть справедливым, эти две фразы, кажется, довольно часто взаимозаменяемы.
Фил Уилер

1
Ах, фабричный метод. Обходной путь для факта, что newэто не метод (в некоторых - по общему признанию - объектных системах).
Донал Феллоуз

Ответы:


44

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

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

public ICardValidator GetCardValidator (string cardType)
{
    switch (cardType.ToLower())
    {
        case "visa":
            return new VisaCardValidator();
        case "mastercard":
        case "ecmc":
            return new MastercardValidator();
        default:
            throw new CreditCardTypeException("Do not recognise this type");
    }
}

Abstract Factory , где у вас есть несколько бетонных фабричных классов (не фабричные методов) , полученных из одного интерфейса , который может возвращать множество различных типов из различных методов.

Подумайте о менеджере по шахматам с разными классами для каждого набора правил.

public class StandardChessRulesFactory : IChessRulesFactory
{
    public IBoardMapper GetBoardMapper()
    {
        return new StandardChessBoardMapper();
    }

    public IKingMover GetKingMover()
    {
        return new StandardChessKingMover();
    }

    public IMoveClock GetMoveClock()
    {
        return new StandardMoveClock();
    }
}

public class HexagonalChessRulesFactory : IChessRulesFactory
{
    public IBoardMapper GetBoardMapper()
    {
        return new HexagonalChessBoardMapper();
    }

    public IKingMover GetKingMover()
    {
        return new HexagonalChessKingMover();
    }

    public IMoveClock GetMoveClock()
    {
        return new StandardMoveClock();
    }
}

public class SpeedChessRulesFactory : IChessRulesFactory
{
    public IBoardMapper GetBoardMapper()
    {
        return new StandardChessBoardMapper();
    }

    public IKingMover GetKingMover()
    {
        return new StandardChessKingMover();
    }

    public IMoveClock GetMoveClock()
    {
        return new SpeedChessMoveClock();
    }
}

Абстрактная фабрика, так же как и стратегия, часто выбирается с помощью фабричного метода, но нет необходимости объединять их, так что это ее собственный шаблон.


3
Правильно ли это объяснение метода Фабрики? Что такое «Шаблон фабричного метода основан на наследовании, поскольку создание объекта делегируется подклассам, которые реализуют фабричный метод для создания объектов». Так что пример больше похож на Static Factory.
SerG

@SerG Ну, честно говоря, вы взяли эту цитату из Википедии, на странице, которая читалась совсем по-другому три года назад. Я бы сказал, что текущая страница Википедии противоречит сама себе в нескольких местах, но у меня нет желания вмешиваться в это. Оглядываясь назад, я бы признал, что приведенный мною пример - это особый тип фабричного метода, известный как параметризованный фабричный метод. Но точка разницы между Фабричным Методом и Абстрактной Фабрикой имеет место во всех типах Фабричного Метода.
pdr

2
То же утверждение, что и моя цитата, существует в GoF "Design Patterns". И Параметризованный FM также описан там.
SerG

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

Вы должны четко указать в своем ответе, что ваш пример - это не типичный шаблон фабричного метода, а некоторая специализация, называемая параметризованным фабричным методом. И напиши об определении типичного фабричного метода, потому что он вводит в заблуждение прямо сейчас. Я только что узнал о шаблоне фабричного метода, я все понял и затем прочитал ответ, который показывает шаблон фабричного метода как нечто иное, и я был сбит с толку. Нет информации о том, что этот пример не является типичным шаблоном фабричного метода. Спасибо SerG за указание этого в комментарии.
17
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.