Различия между абстрактным узором Фабрика и фабричный метод


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

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

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

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

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

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

любая помощь, особенно с последним вопросом, была бы весьма признательна.

14 326

14 ответов:

Разница Между Двумя

потому что фабричный метод-это просто метод, он может быть переопределен в подкласс, отсюда и вторая половина вашей цитаты:

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

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

абстрактная фабрика-это объект, который имеет несколько методов фабрики на ней. Выглядящий в первой половине вашей цитаты:

... с абстрактным заводским шаблоном, класс делегирует ответственность объекта инстанцирование другому объекту через состав...

они говорят, что есть объект A, который хочет сделать объект Foo. Вместо того, чтобы сделать сам объект Foo (например, с помощью Заводского метода), он получит разные объект (абстрактная фабрика) для создания Foo объект.

Примеры Кода

чтобы показать вам разницу, вот метод фабрики в использовании:

class A {
    public void doSomething() {
        Foo f = makeFoo();
        f.whatever();   
    }

    protected Foo makeFoo() {
        return new RegularFoo();
    }
}

class B extends A {
    protected Foo makeFoo() {
        //subclass is overriding the factory method 
        //to return something different
        return new SpecialFoo();
    }
}

и вот абстрактная фабрика в использовании:

class A {
    private Factory factory;

    public A(Factory factory) {
        this.factory = factory;
    }

    public void doSomething() {
        //The concrete class of "f" depends on the concrete class
        //of the factory passed into the constructor. If you provide a
        //different factory, you get a different Foo object.
        Foo f = factory.makeFoo();
        f.whatever();
    }
}

interface Factory {
    Foo makeFoo();
    Bar makeBar();
    Aycufcn makeAmbiguousYetCommonlyUsedFakeClassName();
}

//need to make concrete factories that implement the "Factory" interface here

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

enter image description here

метод фабрики - это просто метод, используемый для создания объектов класса. Обычно он добавляется в корень aggregate (Order класс имеет метод, называемый CreateOrderLine)

enter image description here

абстрактная фабрика

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

interface IMessageQueueFactory
{
  IMessageQueue CreateOutboundQueue(string name);
  IMessageQueue CreateReplyQueue(string name);
}

public class AzureServiceBusQueueFactory : IMessageQueueFactory
{
      IMessageQueue CreateOutboundQueue(string name)
      {
           //init queue
           return new AzureMessageQueue(/*....*/);
      }

      IMessageQueue CreateReplyQueue(string name)
      {
           //init response queue
           return new AzureResponseMessageQueue(/*....*/);
      }

}

public class MsmqFactory : IMessageQueueFactory
{
      IMessageQueue CreateOutboundQueue(string name)
      {
           //init queue
           return new MsmqMessageQueue(/*....*/);
      }

      IMessageQueue CreateReplyQueue(string name)
      {
           //init response queue
           return new MsmqResponseMessageQueue(/*....*/);
      }
}

метод фабрики

проблема в HTTP-серверах заключается в том, что нам всегда нужен ответ на каждый запрос.

public interface IHttpRequest
{
    // .. all other methods ..

    IHttpResponse CreateResponse(int httpStatusCode);
}

без завода метод, пользователи HTTP-сервера (т. е. программисты) будут вынуждены использовать конкретные классы реализации, которые побеждают цель IHttpRequest интерфейс.

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

резюме

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

следует проявлять осторожность при использовании заводских методов, так как легко сломать LSP ( Принцип подстановки Лискова) при создании объектов.

разница между абстрактно-факторным и заводским дизайном заключается в следующем:

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

Реализация Шаблона Заводского Метода:Factory Method UML

Реализация Абстрактно-Факторного Шаблона:

Abstract Factory UML

абстрактная фабрика-это интерфейс для создания связанных продуктов, но метод фабрики-это только один метод. Абстрактная фабрика может быть реализована несколькими заводскими методами.

Abstract Factory UML

рассмотрим этот пример для удобства понимания.

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

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

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

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

в этом случае BundleFactory - это абстрактная Фабрика, BroadbandFactory,PhonelineFactory и MobileFactory это Factory. Просто больше эти заводы будут Метод Фабрики для инициализации отдельных продуктов.

Se пример кода ниже:

public class BroadbandFactory : IFactory {
    public static Broadband CreateStandardInstance() {
        // broadband product creation logic goes here
    }
}

public class PhonelineFactory : IFactory {
    public static Phoneline CreateStandardInstance() {
        // phoneline product creation logic goes here
    }
}

public class MobileFactory : IFactory {
    public static Mobile CreateStandardInstance() {
        // mobile product creation logic goes here
    }
}

public class BundleFactory : IAbstractFactory {

    public static Bundle CreateBundle() {
        broadband = BroadbandFactory.CreateStandardInstance();
        phoneline = PhonelineFactory.CreateStandardInstance();
        mobile = MobileFactory.CreateStandardInstance();

        applySomeDiscountOrWhatever(broadband, phoneline, mobile);
    }

    private static void applySomeDiscountOrWhatever(Broadband bb, Phoneline pl, Mobile m) {
        // some logic here
    }
}

основное различие между абстрактной фабрикой и заводским методом заключается в том, что абстрактная Фабрика реализуется композицией; но Заводской метод реализуется по наследованию.

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

Я не собираюсь воспроизводить диаграммы UML здесь, поскольку их можно найти во многих местах. Я хочу приведите примеры кода; однако, потому что я думаю, что объединение примеров из двух лучших ответов в этом потоке даст лучшую демонстрацию, чем любой ответ в одиночку. Кроме того, я добавил терминологию, используемую в книге (GoF), к именам классов и методов.

Абстрактная Фабрика

  1. самый важный момент, чтобы понять, что абстрактная фабрика это вводят в клиент. Вот почему мы говорим, что Абстрактный Завод реализуется по составу. Часто инъекция зависимости фреймворк выполнит эту задачу; но фреймворк не требуется для Ди.
  2. второй важный момент заключается в том, что бетонные заводы здесь несколько не реализация Заводского метода! Пример кода для фабрики Метода показана ниже.
  3. и, наконец, третий момент-это отношения между продукты: в этом случае исходящие и ответные очереди. Один бетон фабрика производит очереди Azure, другой MSMQ. Гоф ссылается на это отношение продукта как "семья" и важно быть помните, что семья в данном случае не означает иерархию классов.
public class Client {
    private final AbstractFactory_MessageQueue factory;

    public Client(AbstractFactory_MessageQueue factory) {
        // The factory creates message queues either for Azure or MSMQ.
        // The client does not know which technology is used.
        this.factory = factory;
    }

    public void sendMessage() {
        //The client doesn't know whether the OutboundQueue is Azure or MSMQ.
        OutboundQueue out = factory.createProductA();
        out.sendMessage("Hello Abstract Factory!");
    }

    public String receiveMessage() {
        //The client doesn't know whether the ReplyQueue is Azure or MSMQ.
        ReplyQueue in = factory.createProductB();
        return in.receiveMessage();
    }
}

public interface AbstractFactory_MessageQueue {
    OutboundQueue createProductA();
    ReplyQueue createProductB();
}

public class ConcreteFactory_Azure implements AbstractFactory_MessageQueue {
    @Override
    public OutboundQueue createProductA() {
        return new AzureMessageQueue();
    }

    @Override
    public ReplyQueue createProductB() {
        return new AzureResponseMessageQueue();
    }
}

public class ConcreteFactory_Msmq implements AbstractFactory_MessageQueue {
    @Override
    public OutboundQueue createProductA() {
        return new MsmqMessageQueue();
    }

    @Override
    public ReplyQueue createProductB() {
        return new MsmqResponseMessageQueue();
    }
}

Метод Фабрики

  1. самый важный момент, чтобы понять здесь, что ConcreteCreator и клиент. Другими словами, клиент является подклассом, родитель которого определяет factoryMethod(). Вот почему мы говорим, что Фабрика Метод реализуется путем наследования.
  2. второй критический момент заключается в том, чтобы помнить, что заводской метод Шаблон - это не что иное, как специализация шаблонного метода Узор. Эти два шаблона имеют одинаковую структуру. Только они различаются по назначению. Заводской метод является творческим (он строит что-то), тогда как метод шаблона является поведенческим (он вычисляет нечто.)
  3. и, наконец, третий момент, чтобы отметить, что Creator (родителя) класс вызывает свой собственный factoryMethod(). Если мы удалим anOperation() из родительского класса, оставляя только один метод позади, это больше не шаблон Заводского метода. Иначе говоря, Фабричный метод не может быть реализован менее чем двумя методами родительский класс; и один должен вызывать другой.
public abstract class Creator {
    public void anOperation() {
        Product p = factoryMethod();
        p.whatever();
    }

    protected abstract Product factoryMethod();
}

public class ConcreteCreator extends Creator {
    @Override
    protected Product factoryMethod() {
        return new ConcreteProduct();
    }
}

накл. & Различные Модели Фабрики

имейте в виду, что хотя GoF определяют два разных заводских шаблона, это не единственные существующие заводские шаблоны. Они даже не обязательно являются наиболее часто используемыми заводскими образцами. Известный третий пример-статический Заводской шаблон Джоша Блоха из эффективной Java. Книга Head First Design Patterns включает в себя еще один шаблон, который они называют простой фабрикой.

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

давайте проясним, что большую часть времени в производственном коде мы используем абстрактный фабричный шаблон, потому что класс A запрограммирован с интерфейсом B. И A должен создавать экземпляры B. Поэтому A должен иметь заводской объект для создания экземпляров B. Поэтому A не зависит от какого-либо конкретного экземпляра B. надеюсь, что это поможет.

понять различия в мотивации:

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

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

Простой (заимствуя идею у Гофа) - это графический интерфейс приложений, сказать, виртуальный монитор, который эмулирует поискать-Ан-чувствую РС или Mac или Fedora ОС. Вот, например, когда все объекты виджетов, таких как окна, кнопки и т. д. есть вариант MS за исключением полосы прокрутки, которая получена из варианта MAC, назначение инструмента плохо работает.

Эти вышеприведенные случаи формируют фундаментальную потребность Абстрактный Узор Завод.

С другой стороны, представьте, что вы пишете фреймворк, чтобы многие люди могли создавать различные инструменты (такие, как в приведенных выше примерах) С помощью вашего фреймворка. По самой идее рамки, вам не нужно, хотя вы не могли бы использовать конкретные объекты в вашем логика. Вы скорее ставите некоторые контракты высокого уровня между различными объектами и тем, как они взаимодействуют. В то время как вы (как разработчик фреймворка) оставайтесь на очень абстрактном уровне, каждый строитель инструмента вынужден следовать вашим фреймворкам-конструкциям. Однако, они (строители инструмент) имеют свободу решать, какой объект будет построен и как все объекты, которые они создают будут взаимодействовать. В отличие от предыдущего случая ( абстрактного фабричного рисунка), то (как создатель фреймворка) Не нужно работать с конкретными объектами в этом случае; а может остаться на уровне договора объектов. Кроме того, в отличие от второй части предыдущих мотиваций, вы или разработчики инструментов никогда не сталкиваетесь с ситуациями смешивания объектов из вариантов. Здесь, в то время как код платформы остается на уровне контракта, каждый инструмент-строитель ограничен (по характеру самого дела) для использования собственных объектов. Создание объектов в этом случае делегируется каждому разработчику и поставщикам фреймворков просто предоставляются единые методы для создания и возврата объектов. Такие методы неизбежны для разработчика фреймворка, чтобы продолжить их код и имеет специальное имя под названием метод фабрики ( шаблон Заводского метода для базового шаблона).

Несколько Замечаний:

  • если вы знакомы с "шаблонным методом", то вы увидите эту фабрику методы часто вызываются из шаблонных методов в случае программ, относящихся к любой форме фреймворка. Напротив, шаблонные методы прикладных программ часто являются простой реализацией конкретного алгоритма и не имеют заводских методов.
  • кроме того, для полноты мысли, используя платформу (упомянутые выше), когда инструмент-строитель строит инструмент, внутри каждого метода фабрики, вместо того, чтобы создавать конкретный объект, он/она может далее делегируйте ответственность объекту абстрактной фабрики при условии, что инструментальный конструктор предвидит варианты конкретных объектов для будущих расширений.

Пример Кода:

//Part of framework-code
BoardGame {
    Board createBoard() //factory method. Default implementation can be provided as well
    Piece createPiece() //factory method

    startGame(){        //template method
         Board borad = createBoard()
         Piece piece = createPiece()
         initState(board, piece)
    }
}


//Part of Tool-builder code
Ludo inherits  BoardGame {
     Board createBoard(){ //overriding of factory method
         //Option A: return new LudoBoard() //Lodu knows object creation
         //Option B: return LudoFactory.createBoard() //Lodu asks AbstractFacory
     }
….
}

//Part of Tool-builder code
Chess inherits  BoardGame {
    Board createBoard(){ //overriding of factory method
        //return a Chess board
    }
    ….
}
  1. мой первый вопрос касается абстрактной фабрики. Его роль заключается в том, чтобы позволить вам создавать семейства конкретных объектов (которые могут зависеть от того, какую конкретную фабрику вы используете), а не только один конкретный объект?

да. Цель абстрактной фабрики:

обеспечить интерфейс для создания семейств связанных или зависимых объектов без указания их конкретных занятия.


  1. возвращает ли абстрактная фабрика только один очень большой объект или много объектов в зависимости от того, какие методы вы вызываете?

в идеале он должен возвращать один объект на метод, вызываемый клиентом.

  1. Я понимаю, что шаблон метода фабрики имеет интерфейс Создателя, который заставит ConcreteCreator отвечать за знание того, какой конкретный продукт создать экземпляр. Это то, что он означает, используя наследование для обработки экземпляра объекта?

да. Фабричный метод использует наследование.

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

AbstractFactory определяет FactoryMethod и ConcreteFactory отвечает за построение ConcreteProduct. Просто следуйте примеру кода в этомстатьи.

вы можете найти более подробную информацию в соответствующих сообщениях SE:

в чем основная разница между заводскими и абстрактными заводскими узорами?

шаблоны проектирования: завод против Заводского метода против абстрактной фабрики

чтобы сделать его очень простым с минимальным интерфейсом и пожалуйста, сосредоточьтесь "/ / 1":

class FactoryProgram
    {
        static void Main()
        {
            object myType = Program.MyFactory("byte");
            Console.WriteLine(myType.GetType().Name);

            myType = Program.MyFactory("float"); //3
            Console.WriteLine(myType.GetType().Name);

            Console.ReadKey();
        }

        static object MyFactory(string typeName)
        {
            object desiredType = null; //1
            switch (typeName)
            {
                case "byte": desiredType = new System.Byte(); break; //2
                case "long": desiredType = new System.Int64(); break;
                case "float": desiredType = new System.Single(); break;
                default: throw new System.NotImplementedException();
            }
            return desiredType;
        }
    }

вот важные моменты: 1. Фабричные и абстрактные механизмы должны использовать наследование (System.Объект-> байт, плавающее ...); так что если у вас есть наследование в программе, то фабрика(абстрактная фабрика не будет там, скорее всего) уже существует по дизайну 2. Создатель (MyFactory) знает о конкретном типе, поэтому возвращает объект конкретного типа вызывающему (Main); в абстрактной фабрике возвращаемый тип будет Взаимодействие.

interface IVehicle { string VehicleName { get; set; } }
interface IVehicleFactory
    {
        IVehicle CreateSingleVehicle(string vehicleType);
    }
class HondaFactory : IVehicleFactory
    {
        public IVehicle CreateSingleVehicle(string vehicleType)
        {
            switch (vehicleType)
            {
                case "Sports": return new SportsBike();
                case "Regular":return new RegularBike();
                default: throw new ApplicationException(string.Format("Vehicle '{0}' cannot be created", vehicleType));
            }
        }
    }
class HeroFactory : IVehicleFactory
    {
        public IVehicle CreateSingleVehicle(string vehicleType)
        {
            switch (vehicleType)
            {
                case "Sports":  return new SportsBike();
                case "Scooty": return new Scooty();
                case "DarkHorse":return new DarkHorseBike();
                default: throw new ApplicationException(string.Format("Vehicle '{0}' cannot be created", vehicleType));
            }
        }
    }

class RegularBike : IVehicle { public string VehicleName { get { return "Regular Bike- Name"; } set { VehicleName = value; } } }
class SportsBike : IVehicle { public string VehicleName { get { return "Sports Bike- Name"; } set { VehicleName = value; } } }
class RegularScooter : IVehicle { public string VehicleName { get { return "Regular Scooter- Name"; } set { VehicleName = value; } } }
class Scooty : IVehicle { public string VehicleName { get { return "Scooty- Name"; } set { VehicleName = value; } } }
class DarkHorseBike : IVehicle { public string VehicleName { get { return "DarkHorse Bike- Name"; } set { VehicleName = value; } } }

class Program
{
    static void Main(string[] args)
    {
        IVehicleFactory honda = new HondaFactory(); //1
        RegularBike hondaRegularBike = (RegularBike)honda.CreateSingleVehicle("Regular"); //2
        SportsBike hondaSportsBike = (SportsBike)honda.CreateSingleVehicle("Sports");
        Console.WriteLine("******* Honda **********"+hondaRegularBike.VehicleName+ hondaSportsBike.VehicleName);

        IVehicleFactory hero = new HeroFactory();
        DarkHorseBike heroDarkHorseBike = (DarkHorseBike)hero.CreateSingleVehicle("DarkHorse");
        SportsBike heroSportsBike = (SportsBike)hero.CreateSingleVehicle("Sports");
        Scooty heroScooty = (Scooty)hero.CreateSingleVehicle("Scooty");
        Console.WriteLine("******* Hero **********"+heroDarkHorseBike.VehicleName + heroScooty.VehicleName+ heroSportsBike.VehicleName);

        Console.ReadKey();
    }
}

важные моменты: 1. Требование: Honda создаст "обычный", "спортивный", но Hero создаст "темный конь", "спорт"и " скутер". 2. почему два интерфейса? Одно для типа изготовителя (IVehicleFactory) и другое для фабрики продукта(IVehicle); другой путь понять 2 интерфейса абстрактная фабрика совсем о создании родственных объектов 2. Улов-это возвращение детей IVehicleFactory и IVehicle (вместо бетона на заводе); поэтому я получаю родителя переменная (IVehicle); затем я создаю фактический конкретный тип, вызывая CreateSingleVehicle и затем бросая родительский объект в фактический дочерний объект. Что будет, если я сделаю RegularBike heroRegularBike = (RegularBike)hero.CreateSingleVehicle("Regular");; вы получите ApplicationException и именно поэтому нам нужна общая абстрактная фабрика, которую я бы объяснил, если потребуется. Надеюсь, что это поможет от новичка до промежуточной аудитории.

Пример Из Реальной Жизни. (Легко запомнить)

завод

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

Абстрактная Фабрика

Теперь рассмотрим то же самое пример двери. Вы можете пойти к плотнику, или вы можете пойти в магазин пластиковых дверей или магазин ПВХ. Все двери фабрики. Исходя из ситуации, вы решаете, к какой фабрике вам нужно подойти. Это как абстрактная Фабрика.

Я объяснил здесь как шаблон Заводского метода, так и абстрактный заводской шаблон, начиная с того, что они не используют их, объясняя проблемы, а затем решая проблемы с помощью вышеизложенного узоры https://github.com/vikramnagineni/Design-Patterns/tree/master

Я бы предпочел абстрактный Завод над заводским методом в любое время. Из примера Тома Даллинга (отличное объяснение кстати) выше мы видим, что абстрактная Фабрика более композиционна в том, что все, что нам нужно сделать, это передать другую фабрику конструктору (инъекция зависимостей конструктора здесь используется). Но фабричный метод требует от нас ввести новый класс (больше вещей для управления) и использовать подклассы. Всегда предпочитайте композицию наследованию.

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

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

как метко говорит Гоф: абстрактная Фабрика предоставляет интерфейс для создания семейств связанных или зависимых объектов без указания их конкретные классы.

        public class Client {
            public static void main(String[] args) {
               ZooFactory zooFactory = new HerbivoreZooFactory();       
               Animal animal1 = zooFactory.animal1();
               Animal animal2 = zooFactory.animal2();
               animal1.sound();
               animal2.sound();

               System.out.println();

               AnimalFactory animalFactory = new CowAnimalFactory();
               Animal animal = animalFactory.createAnimal();
               animal.sound();
            }
        }

        public interface Animal {
            public void sound();
        }

        public class Cow implements Animal {

            @Override
            public void sound() {
                System.out.println("Cow moos");
            }

        }

        public class Deer implements Animal {

            @Override
            public void sound() {
                System.out.println("Deer grunts");
            }

        }

        public class Hyena implements Animal {

            @Override
            public void sound() {
                System.out.println("Hyena.java");
            }

        }

        public class Lion implements Animal {

            @Override
            public void sound() {
                System.out.println("Lion roars");
            }

        }

        public interface ZooFactory {
            Animal animal1();

            Animal animal2();
        }

        public class CarnivoreZooFactory implements ZooFactory {

            @Override
            public Animal animal1() {
                return new Lion();
            }

            @Override
            public Animal animal2() {
                return new Hyena();
            }

        }

        public class HerbivoreZooFactory implements ZooFactory{

            @Override
            public Animal animal1() {
                return new Cow();
            }

            @Override
            public Animal animal2() {
                return new Deer();
            }

        }

        public interface AnimalFactory {
            public Animal createAnimal();
        }

        public class CowAnimalFactory implements AnimalFactory{

            @Override
            public Animal createAnimal() {
                return new Cow();
            }

        }

        public class DeerAnimalFactory implements AnimalFactory{

            @Override
            public Animal createAnimal() {
                return new Deer();
            }

        }

        public class HyenaAnimalFactory implements AnimalFactory{

            @Override
            public Animal createAnimal() {
                return new Hyena();
            }

        }

        public class LionAnimalFactory implements AnimalFactory{

            @Override
            public Animal createAnimal() {
                return new Lion();
            }

        }