Заводской образец. Когда использовать фабричные методы?

Когда лучше использовать фабричные методы внутри объекта вместо фабричного класса?


person Community    schedule 16.09.2008    source источник
comment
См. softwareengineering.stackexchange.com/questions/253254/   -  person tkit    schedule 08.08.2017
comment
Чтобы узнать, когда использовать фабричный метод, см .: Применимость для шаблона фабричного метода.   -  person jaco0646    schedule 02.01.2021


Ответы (16)


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

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

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

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

public interface IThingFactory
{
    Thing GetThing(string theString);
}

public class ThingFactory : IThingFactory
{
    public Thing GetThing(string theString)
    {
        return new Thing(theString, firstDependency, secondDependency);
    }
}

Итак, теперь потребитель ThingFactory может получить Thing без необходимости знать о зависимостях Thing, за исключением строковых данных, которые поступают от потребителя.

person kyoryu    schedule 12.03.2010
comment
Где конкретная реализация GetThing () извлекает значения firstDependency и secondDependency? - person Mikeyg36; 31.05.2013
comment
Может ли кто-нибудь сказать мне, как это отвечает на вопрос ОП? Здесь просто описывается, что такое «Factory Pattern», а затем добавляется пример «Factory Method», который является лишь одним из трех «Factory Patterns». Другими словами, нигде не вижу сравнения. - person Forethinker; 07.09.2013
comment
В вопросе OP четко упоминается within an object instead of a Factory class. Я думаю, он имел в виду сценарий, в котором вы делаете ctor частным и используете статический метод для создания экземпляра класса (создания объекта). Но чтобы следовать этому примеру, нужно сначала создать экземпляр класса ThingFactory, чтобы получить Thing объекты, что в действительности делает это Factory class. - person atiyar; 21.04.2014
comment
Извините, но объяснение - дерьмо, потому что конструктор также может быть написан таким образом, чтобы скрыть зависимости. Ключевая справочная информация, которую вы хотите отделить от информации о создании зависимости от управления зависимостями, отсутствует. Кроме того, вопрос был об одном классе, ответ никак не связан с этим. - person Christian Hujer; 08.08.2015
comment
ОП спросил когда. Кёрю ответил как. Хотя стиль ответа заслуживает похвалы, в контексте этого вопроса это просто шум. - person 8bitjunkie; 03.11.2015
comment
Отличное объяснение, несмотря на то, что люди здесь его критикуют. Я чувствую, что знаю, как и когда лучше всего использовать Factory Pattern. - person ParkCheolu; 08.04.2017
comment
Этот ответ не описывает шаблон фабричного метода. Слово Метод здесь важно и не относится к Технике, скорее, Метод используется со ссылкой на тот факт, что создание объекта отложено до абстрактного метода. - person Richard Moore; 20.10.2018
comment
Объяснение дерьма - person Mohit Shah; 03.03.2021

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

class Foo{
  public Foo(bool withBar);
}

не так выразительно, как:

class Foo{
  public static Foo withBar();
  public static Foo withoutBar();
}

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

person Rasmus Faber    schedule 30.12.2008
comment
Где здесь класс Factory? - person Koray Tugay; 16.07.2014
comment
@KorayTugay: нет фабричного класса, только фабричные методы. Вопрос в том, когда использовать фабричные методы вместо фабричного класса. Но фабричные методы - это скорее альтернатива конструкторам, чем альтернатива фабричным классам. (Я не знаю, почему главный ответ так высоко оценен, несмотря на то, что речь идет только о фабричных классах). - person Rasmus Faber; 16.07.2014
comment
Следует отметить, что статические фабричные методы полностью отличаются от шаблона проектирования «Банда четырех: фабричный метод». - person jaco0646; 26.07.2016

Одна ситуация, в которой я лично считаю, что отдельные классы Factory имеют смысл, - это когда конечный объект, который вы пытаетесь создать, зависит от нескольких других объектов. Например, в PHP: предположим, что у вас есть объект House, который, в свою очередь, имеет объекты Kitchen и LivingRoom, а объект LivingRoom также имеет объект TV внутри.

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

Альтернативой является следующее (внедрение зависимости, если вам нравится этот модный термин):

$TVObj = new TV($param1, $param2, $param3);
$LivingroomObj = new LivingRoom($TVObj, $param1, $param2);
$KitchenroomObj = new Kitchen($param1, $param2);
$HouseObj = new House($LivingroomObj, $KitchenroomObj);

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

class HouseFactory {
    public function create() {
        $TVObj = new TV($param1, $param2, $param3);
        $LivingroomObj = new LivingRoom($TVObj, $param1, $param2);
        $KitchenroomObj = new Kitchen($param1, $param2);
        $HouseObj = new House($LivingroomObj, $KitchenroomObj);

        return $HouseObj;
    }
}

$houseFactory = new HouseFactory();
$HouseObj = $houseFactory->create();

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

person Mahn    schedule 11.05.2012
comment
Как бы кто-то мог провести модульный тест на этом? Я думал, что использование ключевого слова new в классе считалось плохой практикой, потому что его нельзя тестировать. Или фабрика должна быть исключением из этого правила? - person AgmLauncher; 08.10.2013
comment
@AgmLauncher У меня тоже был тот же вопрос, когда я начал работать с модульным тестированием, проверьте: stackoverflow.com/questions/10128780/ - person Mahn; 09.10.2013
comment
Не понял. Как именно в класс HouseFactory передаются параметры для создания различных объектов? - person atiyar; 21.04.2014
comment
@NerotheZero Я пропустил это в примере для простоты, но вы бы либо жестко запрограммировали их внутри класса, либо передали бы их как аргументы HouseFactory::create. Было бы нормально, например, иметь вызов create, такой как $houseFactory->create($TVParam1, $TVParam2, $livingRoomParam1, $livingRoomParam2); и т. Д. - person Mahn; 05.05.2014
comment
@Mahn, разве в конце концов у вас не будет много параметров? - person Pacerier; 17.06.2014
comment
@Pacerier - это то, что вам нужно решить, как моделировать, в зависимости от ваших потребностей, но вы не всегда должны передавать каждый параметр методу create. Например. если ваш House всегда будет иметь одинаковый тип LivingRoom, тогда имеет смысл жестко запрограммировать его параметры в фабричном классе, а не передавать его в качестве аргументов. Или вы можете предоставить type аргумент вашему HouseFactory::create методу, если у вас есть несколько видов LivingRoom и внутри есть переключатель с параметрами, жестко запрограммированными для каждого типа. - person Mahn; 17.06.2014
comment
@Pacerier (продолжает) все дело в конечном использовании в конце дня. При разработке HouseFactory подумайте, каким образом ваши House будут использоваться, и определите оттуда, что обязательно должно быть передано в качестве аргумента, а что может быть жестко закодировано / опущено. - person Mahn; 17.06.2014
comment
хм, я имею в виду, что во время строительства вроде бы работает, но зависимости все еще есть. FactoryBuilder звучит для меня как фасад в этом описании. Если вы столкнетесь с ошибками Дома, вам все равно придется просмотреть все связанные объекты ... только не во время строительства. - person dtc; 23.08.2016
comment
Для этого decorator design pattern удобнее, правда? - person vipin cp; 19.06.2018

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

Давайте конкретизируем «фабричный метод»:

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

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

interface Deliverable 
{
    /*********/
}

abstract class DefaultProducer 
{

    public void taskToBeDone() 
    {   
        Deliverable deliverable = factoryMethodPattern();
    }
    protected abstract Deliverable factoryMethodPattern();
}

class SpecificDeliverable implements Deliverable 
{
 /***SPECIFIC TASK CAN BE WRITTEN HERE***/
}

class SpecificProducer extends DefaultProducer 
{
    protected Deliverable factoryMethodPattern() 
    {
        return new SpecificDeliverable();
    }
}

public class MasterApplicationProgram 
{
    public static void main(String arg[]) 
    {
        DefaultProducer defaultProducer = new SpecificProducer();
        defaultProducer.taskToBeDone();
    }
}
person Prakash Chhipa    schedule 16.07.2013

Они также полезны, когда вам нужно несколько «конструкторов» с одним и тем же типом параметра, но с различным поведением.

person Rik    schedule 16.09.2008

Заводские методы рекомендуется использовать внутри объекта в следующих случаях:

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

Класс абстрактной фабрики рекомендуется использовать в следующих случаях:

  1. Ваш объект не должен зависеть от того, как создаются и проектируются его внутренние объекты.
  2. Группа связанных объектов должна использоваться вместе, и вам необходимо выполнить это ограничение.
  3. Объект должен быть настроен одним из нескольких возможных семейств связанных объектов, которые будут частью вашего родительского объекта.
  4. Требуется поделиться дочерними объектами, показывающими только интерфейсы, но не реализацию.
person Dzianis Yafimau    schedule 26.05.2015

UML от

введите описание изображения здесь

Продукт. Он определяет интерфейс объектов, которые создает метод Factory.

ConcreteProduct: реализует интерфейс продукта.

Создатель: объявляет фабричный метод.

ConcreateCreator: реализует метод Factory для возврата экземпляра ConcreteProduct.

Постановка проблемы: создайте Factory of Games с помощью Factory Methods, который определяет интерфейс игры.

Фрагмент кода:

import java.util.HashMap;


/* Product interface as per UML diagram */
interface Game{
    /* createGame is a complex method, which executes a sequence of game steps */
    public void createGame();
}

/* ConcreteProduct implementation as per UML diagram */
class Chess implements Game{
    public Chess(){

    }
    public void createGame(){
        System.out.println("---------------------------------------");
        System.out.println("Create Chess game");
        System.out.println("Opponents:2");
        System.out.println("Define 64 blocks");
        System.out.println("Place 16 pieces for White opponent");
        System.out.println("Place 16 pieces for Black opponent");
        System.out.println("Start Chess game");
        System.out.println("---------------------------------------");
    }
}
class Checkers implements Game{
    public Checkers(){

    }
    public void createGame(){
        System.out.println("---------------------------------------");
        System.out.println("Create Checkers game");
        System.out.println("Opponents:2 or 3 or 4 or 6");
        System.out.println("For each opponent, place 10 coins");
        System.out.println("Start Checkers game");
        System.out.println("---------------------------------------");
    }
}
class Ludo implements Game{
    public Ludo(){

    }
    public void createGame(){
        System.out.println("---------------------------------------");
        System.out.println("Create Ludo game");
        System.out.println("Opponents:2 or 3 or 4");
        System.out.println("For each opponent, place 4 coins");
        System.out.println("Create two dices with numbers from 1-6");
        System.out.println("Start Ludo game");
        System.out.println("---------------------------------------");
    }
}

/* Creator interface as per UML diagram */
interface IGameFactory {
    public Game getGame(String gameName);
}

/* ConcreteCreator implementation as per UML diagram */
class GameFactory implements IGameFactory {

     HashMap<String,Game> games = new HashMap<String,Game>();
    /*  
        Since Game Creation is complex process, we don't want to create game using new operator every time.
        Instead we create Game only once and store it in Factory. When client request a specific game, 
        Game object is returned from Factory instead of creating new Game on the fly, which is time consuming
    */

    public GameFactory(){

        games.put(Chess.class.getName(),new Chess());
        games.put(Checkers.class.getName(),new Checkers());
        games.put(Ludo.class.getName(),new Ludo());        
    }
    public Game getGame(String gameName){
        return games.get(gameName);
    }
}

public class NonStaticFactoryDemo{
    public static void main(String args[]){
        if ( args.length < 1){
            System.out.println("Usage: java FactoryDemo gameName");
            return;
        }

        GameFactory factory = new GameFactory();
        Game game = factory.getGame(args[0]);
        if ( game != null ){                    
            game.createGame();
            System.out.println("Game="+game.getClass().getName());
        }else{
            System.out.println(args[0]+  " Game does not exists in factory");
        }           
    }
}

выход:

java NonStaticFactoryDemo Chess
---------------------------------------
Create Chess game
Opponents:2
Define 64 blocks
Place 16 pieces for White opponent
Place 16 pieces for Black opponent
Start Chess game
---------------------------------------
Game=Chess

В этом примере показан класс Factory путем реализации FactoryMethod.

  1. Game - это интерфейс для всех типов игр. Он определяет сложный метод: createGame()

  2. Chess, Ludo, Checkers - это разные варианты игр, в которых реализованы createGame()

  3. public Game getGame(String gameName) FactoryMethod в IGameFactory классе

  4. GameFactory в конструкторе предварительно создает разные типы игр. Он реализует IGameFactory фабричный метод.

  5. Имя игры передается как аргумент командной строки NotStaticFactoryDemo

  6. getGame в GameFactory принимает название игры и возвращает соответствующий объект Game.

Завод:

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

FactoryMethod

Определите интерфейс для создания объекта, но позвольте подклассам решать, какой класс создать. Метод Factory позволяет классу отложить создание экземпляра до подклассов.

Пример использования:

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

person Ravindra babu    schedule 08.03.2016
comment
спасибо за ваш основной раздел, он краток для меня. но, это невообразимо, что getArea () является фабричным методом в интерфейсе формы, потому что метод getArea НИКОГДА не создает экземпляр какого-либо класса, он просто выполняет расчет .review, который определяет интерфейс для создания объект, но позвольте подклассам решать, какой класс создать, пожалуйста. - person reco; 13.12.2017
comment
getArea() не является фабричным методом вообще. - person Cranio; 13.02.2018
comment
У меня другое мнение - эксперты, пожалуйста, подтвердите и сделайте пометки. 1. Клиенту (или вызывающему) нужен объект интереса ... следовательно, не нужно вызывать new GameFactory (), а класс Factory должен иметь статический getInstance () 2. Также, если это так, то games.put (Chess.class.getName (), new Chess ()); всегда будет возвращать одну и ту же ссылку на Chess [если реализовано как статическое] - как наиболее эффективно справиться с этим сценарием? - person Arnab Dutta; 18.07.2018
comment
Я привел пример нестатической Factory. Вы можете реализовать это с помощью статических блоков и методов, если хотите. Относительно ваших запросов: 1. Клиент позвонит в Factory, чтобы получить игру. 2. Я помещаю объект один раз, и все Get будут возвращать один и тот же экземпляр - для каждого получения возвращается одна и та же ссылка Chess. - person Ravindra babu; 19.07.2018

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

person Brad Wilson    schedule 16.09.2008

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

WCF использует классы ServiceHostFactory для получения объектов ServiceHost в различных ситуациях. Стандартный ServiceHostFactory используется IIS для получения экземпляров ServiceHost для файлов .svc, но WebScriptServiceHostFactory используется для служб, возвращающих сериализации клиентам JavaScript. ADO.NET Data Services имеет свой собственный специальный DataServiceHostFactory, а ASP.NET имеет свой ApplicationServicesHostFactory, поскольку его службы имеют частные конструкторы.

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

person Mark Cidade    schedule 16.09.2008

Рассмотрим сценарий, когда вам нужно разработать классы Order и Customer. Для простоты и начальных требований вы не чувствуете необходимости в фабрике для класса Order и заполняете свое приложение множеством операторов new Order (). Вещи работают хорошо.

Теперь появляется новое требование, согласно которому объект Order не может быть создан без ассоциации с клиентом (новая зависимость). Теперь у вас есть следующие соображения.

1- Вы создаете перегрузку конструктора, которая будет работать только для новых реализаций. (Недопустимо). 2- Вы меняете подписи Order () и меняете каждый вызов. (Не лучшая практика и настоящая боль).

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

person Muhammad Awais    schedule 09.09.2015

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

public class factoryMethodPattern {
      static String planName = "COMMERCIALPLAN";
      static int units = 3;
      public static void main(String args[]) {
          GetPlanFactory planFactory = new GetPlanFactory();
          Plan p = planFactory.getPlan(planName);
          System.out.print("Bill amount for " + planName + " of  " + units
                        + " units is: ");
          p.getRate();
          p.calculateBill(units);
      }
}

abstract class Plan {
      protected double rate;

      abstract void getRate();

      public void calculateBill(int units) {
            System.out.println(units * rate);
      }
}

class DomesticPlan extends Plan {
      // @override
      public void getRate() {
            rate = 3.50;
      }
}

class CommercialPlan extends Plan {
      // @override
      public void getRate() {
            rate = 7.50;
      }
}

class InstitutionalPlan extends Plan {
      // @override
      public void getRate() {
            rate = 5.50;
      }
}

class GetPlanFactory {

      // use getPlan method to get object of type Plan
      public Plan getPlan(String planType) {
            if (planType == null) {
                  return null;
            }
            if (planType.equalsIgnoreCase("DOMESTICPLAN")) {
                  return new DomesticPlan();
            } else if (planType.equalsIgnoreCase("COMMERCIALPLAN")) {
                  return new CommercialPlan();
            } else if (planType.equalsIgnoreCase("INSTITUTIONALPLAN")) {
                  return new InstitutionalPlan();
            }
            return null;
      }
}
person Samet ÖZTOPRAK    schedule 08.08.2017

Любой класс, откладывающий создание объекта своему подклассу для объекта, с которым он должен работать, можно рассматривать как пример шаблона Factory.

Я подробно упомянул в другом ответе на https://stackoverflow.com/a/49110001/504133

person nits.kk    schedule 07.03.2018

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

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

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

Посмотрите на этот пример: https://connected2know.com/programming/java-factory-pattern/. А теперь представьте, что вы хотите принести новое Животное. В классе Factory вам нужно изменить Factory, но в методе factory вам нужно только добавить новый подкласс.

person tagus    schedule 27.11.2019

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

Я нашел это полезным шаблоном, особенно там, где я не могу заменить ORM и не могу эффективно создавать экземпляры многих объектов из объединений таблиц БД или хранимых процедур.

person jonfm    schedule 16.09.2008

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

Заводской петтер использует полиморфизм, внедрение зависимостей и инверсию управления.

Заявленная цель Factory Patterns: Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

Итак, предположим, что вы создаете операционную систему или фреймворк, и вы создаете все отдельные компоненты.

Вот простой пример концепции Factory Pattern в PHP. Возможно, я не на 100% разбираюсь в этом, но он предназначен для того, чтобы служить простым примером. Я не эксперт.

class NumbersFactory {
    public static function makeNumber( $type, $number ) {
        $numObject = null;
        $number = null;

        switch( $type ) {
            case 'float':
                $numObject = new Float( $number );
                break;
            case 'integer':
                $numObject = new Integer( $number );
                break;
            case 'short':
                $numObject = new Short( $number );
                break;
            case 'double':
                $numObject = new Double( $number );
                break;
            case 'long':
                $numObject = new Long( $number );
                break;
            default:
                $numObject = new Integer( $number );
                break;
        }

        return $numObject;
    }
}

/* Numbers interface */
abstract class Number {
    protected $number;

    public function __construct( $number ) {
        $this->number = $number;
    }

    abstract public function add();
    abstract public function subtract();
    abstract public function multiply();
    abstract public function divide();
}
/* Float Implementation */
class Float extends Number {
    public function add() {
        // implementation goes here
    }

    public function subtract() {
        // implementation goes here
    }

    public function multiply() {
        // implementation goes here
    }

    public function divide() {
        // implementation goes here
    }
}
/* Integer Implementation */
class Integer extends Number {
    public function add() {
        // implementation goes here
    }

    public function subtract() {
        // implementation goes here
    }

    public function multiply() {
        // implementation goes here
    }

    public function divide() {
        // implementation goes here
    }
}
/* Short Implementation */
class Short extends Number {
    public function add() {
        // implementation goes here
    }

    public function subtract() {
        // implementation goes here
    }

    public function multiply() {
        // implementation goes here
    }

    public function divide() {
        // implementation goes here
    }
}
/* Double Implementation */
class Double extends Number {
    public function add() {
        // implementation goes here
    }

    public function subtract() {
        // implementation goes here
    }

    public function multiply() {
        // implementation goes here
    }

    public function divide() {
        // implementation goes here
    }
}
/* Long Implementation */
class Long extends Number {
    public function add() {
        // implementation goes here
    }

    public function subtract() {
        // implementation goes here
    }

    public function multiply() {
        // implementation goes here
    }

    public function divide() {
        // implementation goes here
    }
}

$number = NumbersFactory::makeNumber( 'float', 12.5 );
person Robert Rocha    schedule 01.01.2015
comment
Я понимаю, что здесь происходит, но не понимаю, в чем смысл этого. Что NumbersFactory::makeNumber( 'float', 12.5 ); дает мне просто сказать new Float(12.5);, если я знаю, что мне нужен Float? Вот чего я не понимаю в фабриках ... в чем смысл? - person BadHorsie; 19.10.2015
comment
Он позволяет вам выбирать разные реализации и не связывает вас только с одной. Интерфейс создан, и все реализации должны его гарантировать и соблюдать. - person Robert Rocha; 20.10.2015

введите описание изображения здесь Представьте, что у вас есть разные клиенты с разными предпочтениями. Кому-то нужен Фольксваген, другому Ауди и тд. Одно общее - это машина.

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

Ниже вы можете увидеть пример (ABAP):  введите описание изображения здесь

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

Мы создали три разных автомобиля с помощью только одного метода create ().

Результат:

введите описание изображения здесь

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

person Mykola Tokariev    schedule 24.06.2021