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

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

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

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

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

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

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

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

Ответы

Ответ 1

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

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

Поскольку метод factory - это всего лишь метод, он может быть переопределен в подклассе, следовательно, вторая половина цитаты:

... используется шаблон метода factoryнаследование и полагается на подкласс для обработки желаемого объекта конкретизации.

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

Абстрактный factory - это объект, на котором есть несколько методов factory. Глядя на первую половину вашей цитаты:

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

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

Примеры кода

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

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

И здесь используется абстрактный factory:

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

Ответ 2

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

enter image description here

Фабричный метод - это простой метод, используемый для создания объектов в классе. Обычно он добавляется в CreateOrderLine корень (в классе 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 бы IHttpRequest интерфейса IHttpRequest.

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

Резюме

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

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

Ответ 3

Разница между AbstractFactory и Factory заключается в следующем:

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

Factory Реализация шаблона метода: Factory Method UML

Реализация AbstractFactory Pattern:

Abstract Factory UML

Ответ 4

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

Abstract Factory UML

Ответ 5

Основное различие между Абстрактной Фабрикой и Фабричным Методом состоит в том, что Абстрактная Фабрика реализуется Композицией; но фабричный метод реализован по наследству.

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

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

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

  1. Здесь важно понять, что абстрактная фабрика вводится в клиента. Вот почему мы говорим, что Абстрактная Фабрика реализуется Композицией. Часто инфраструктура внедрения зависимостей выполняет эту задачу; но рамки для DI не требуются.
  2. Вторым критическим моментом является то, что конкретные фабрики здесь не являются реализациями Factory Method! Пример кода для Factory Method показан ниже.
  3. И, наконец, третий момент, на который следует обратить внимание, - это взаимосвязь между продуктами: в этом случае очереди исходящих и ответных сообщений. Один бетонный завод производит очереди Azure, другой MSMQ. GoF называет это отношение продукта "семьей", и важно понимать, что семья в данном случае не означает иерархию классов.
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(). Вот почему мы говорим, что Factory Method реализуется по наследству.
  2. Второй критический момент - помнить, что шаблон метода фабрики - это не более чем специализация шаблона метода шаблона. Два шаблона имеют одинаковую структуру. Они отличаются только по назначению. Фабричный метод является креативным (он что-то строит), тогда как шаблонный метод является поведенческим (он что-то вычисляет).
  3. И, наконец, третий момент, на который следует обратить внимание: класс Creator (parent) вызывает свой собственный factoryMethod(). Если мы удалим anOperation() из родительского класса, оставив только один метод, он больше не будет шаблоном Factory Method. Другими словами, фабричный метод не может быть реализован менее чем с двумя методами в родительском классе; и один должен ссылаться на другого.
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 определяет два разных шаблона Factory, они не являются единственными существующими шаблонами Factory. Они даже не являются наиболее часто используемыми фабричными шаблонами. Известным третьим примером является шаблон статической фабрики Джоша Блоха из Effective Java. Книга Head First Design Patterns включает в себя еще одну модель, которую они называют Simple Factory.

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

Ответ 6

Рассмотрим этот пример для простоты понимания.

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

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

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

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

В этом случае BundleFactory является абстрактной фабрикой, BroadbandFactory, PhonelineFactory и MobileFactory является Factory. Чтобы упростить еще, эти фабрики будут иметь фабричный метод для инициализации отдельных продуктов.

Посмотрите пример кода ниже:

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
        // maybe manange some variables and invoke some other methods/services/etc.
    }
}

Надеюсь это поможет.

Ответ 7

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

Ответ 8

  • Мой первый вопрос касается абстрактного factory. Его роль позволяет создавать семьи конкретных объектов (которые могут зависеть от того, какой конкретный factory вы используете), а не только одного конкретного объекта?

Да. Целью Abstract factory является:

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


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

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

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

Да. factory метод использует наследование.

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

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

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

В чем основное отличие шаблонов factory и Abstract factory?

Шаблоны проектирования: factory vs factory метод vs Аннотация Factory

Ответ 9

Понимание различий в мотивах:

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

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

Простая (заимствование идеи из GoF) - это любые приложения графического интерфейса, которые говорят виртуальный монитор, который эмулирует внешний вид MS или Mac или Fedora OS. Здесь, например, когда все объекты виджетов, такие как окно, кнопка и т.д., Имеют вариант MS, за исключением полосы прокрутки, которая получена из варианта MAC, цель инструмента сильно сработала.

  Эти вышеприведенные случаи составляют основную потребность Аннотация <шаблон > w771 > .

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

Несколько заметок:

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

Пример кода:

//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
    }
    ….
}

Ответ 10

Чтобы сделать его очень простым с минимальным интерфейсом и сосредоточьте внимание на "//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. Factory и механизмы AbstractFactory должны использовать наследование (System.Object- > byte, float...); поэтому, если у вас есть наследование в программе, тогда Factory (Аннотация Factory не будет там, вероятно, уже существует) уже существует по дизайну 2. Creator (MyFactory) знает о конкретном типе, поэтому возвращает конкретный тип объекта вызывающему (Main); В абстрактном Factory обратном типе будет интерфейс.

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 создаст "Regular", "Sports", но Hero создаст "DarkHorse", "Sports" и "Scooty". 2. почему два интерфейса? Один для типа производителя (IVehicleFactory), а другой для продукта Factory (IVehicle); другой способ понять 2 интерфейса - это абстрактный Factory - это создание связанных объектов. 2. Уловкой являются возвращаемые дети IVehicleFactory и IVehicle (вместо бетона в factory); поэтому я получаю родительскую переменную (IVehicle); то я создаю конкретный конкретный тип, вызывая CreateSingleVehicle, а затем бросая родительский объект в реальный дочерний объект. Что произойдет, если я сделаю RegularBike heroRegularBike = (RegularBike)hero.CreateSingleVehicle("Regular");; вы получите ApplicationException и почему нам нужен общий абстрактный Factory, который я объясню, если потребуется. Надеюсь, что это помогает от начинающих до промежуточной аудитории.

Ответ 11

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

Factory

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

Аннотация Factory

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

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

Ответ 12

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

Ответ 13

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

Ответ 14

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

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

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

        }

Ответ 15

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

Абстрактная фабрика опирается на композицию объекта: создание объекта осуществляется методами, представленными в интерфейсе фабрики.

Диаграмма высокого уровня фабричной и абстрактной фабричной модели,

diagram

Для получения дополнительной информации о методе Factory, обратитесь к этой статье.

Для получения дополнительной информации о методе Abstract factory, обратитесь к этой статье.

Ответ 16

Абстрактная фабрика: фабрика заводов; фабрика, которая группирует отдельные, но связанные/зависимые фабрики вместе без указания их конкретных классов. Пример абстрактной фабрики

Фабрика: предоставляет способ делегировать логику реализации дочерним классам. Пример фабричного образца