В чем преимущество использования фабричного метода по сравнению с простым? - PullRequest
0 голосов
/ 19 ноября 2018

Я читаю о фабричном методе и простой фабрике.Оказывается, насколько я понимаю, простой фабрики достаточно, и я не вижу варианта использования шаблона фабричного метода.Пожалуйста, прочитайте эту ссылку, https://www.binpress.com/factory-design-pattern/, и я задам мои вопросы.

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

if ('car'==$toyName) {
            $toy = new NyCar();
        } else if ('helicopter'==$toyName) {
            $toy = new NyHelicopter();
        }

Если будет новый тори для Нью-Йорка, нам нужно добавить его здесь.

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

class NySimpleFactory {
    public function createToy($toyName) {
        $toy = null;

        if ('car'==$toyName) {
            $toy = new NyCar();
        } else if ('helicopter'==$toyName) {
            $toy = new NyHelicopter();
        }

        return $toy;
    }
}

class NyToysFactory {

    public $simpleFactory;

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

    public function produceToy($toyName) {
        $toy = null;
        $toy = $this->simpleFactory->createToy($toyName);
        $toy->prepare();
        $toy->package();
        $toy->label();
        return $toy;
    }
}

Затем говорится:

Разработчики быстро заканчивают новый код и передают его фабрикам в США.Через две недели телефон начинает звонить в офисе разработчиков, потому что на нью-йоркской фабрике возникли производственные проблемы.Оказывается, что класс NyToysFactory был изменен разработчиками в удаленной ветке, потому что персонал не хочет делать упаковку и маркировку.Они изменили yieldToy (), удалив его функции label () и package ().

Кажется, что Simple Factory не будет работать в этом сценарии.Мы не хотим, чтобы филиалы в США могли изменять функции yieldToy ().ProduceToy () должен состоять из набора стандартных процедур, а ветви должны отвечать только за создание игрушек для конкретного места.Что если они могут создать абстрактный класс?И созданный ими абстрактный класс будет иметь конкретный метод yieldToy (), который будет реализовывать набор стандартных рабочих процедур, которым должны следовать все ветви.Внутри yieldToy () он вызывает собственный абстрактный метод createToy () для получения игрушечного класса.Таким образом createToy () может инкапсулировать создание объекта и, поскольку он является абстрактным, он делегирует создание своим подклассам.

Вопрос заключается в следующем: a) Что это значит, говоря передачуэто на американские заводы?б) или мы не хотим, чтобы филиалы в США могли модифицировать функции yieldToy ().они все еще могут модифицировать функцию yieldToy, какая разница, если они не могут или могут ее изменить?Я просто не понимаю, почему простая фабрика вообще плоха для следующего примера.

Нет необходимости читать об абстрактной фабрике по этой ссылке

1 Ответ

0 голосов
/ 19 ноября 2018

T ЕГО КОД / ПРОБЛЕМА не отображает абстрактный фабричный или фабричный метод.Принятие решения о том, какой класс создавать экземпляром путем включения параметра, действительно является анти-паттерном, поощряющим нарушение принципа открытого-закрытого типа.

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

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

abstract class ToyFactory
+ createBear(): ToyBear
+ createElephant(): ToyElephant

class USToyFactory extends ToyFactory
+ createBear(): ToyBear -> creates USToyBear
+ createElephant(): ToyElephant -> USToyElephant

abstract class ToyBear
+ playSound()

class USToyBear extends ToyBear
+ playSound()//play US National Anthem

Передача USToyFactory, где ожидается ToyFactory, обеспечивает создание американских игрушек (USToyBear и USToyElephant) - это сила абстрактной фабрики.

Обратите внимание, что продукты , медведи, слоны и т. Д., Известны как AoT (раньше времени).

Фабричный метод

Фабричный метод - это всеоб отсрочке создания экземпляров для подклассов.

abstract class Dashboard
+ createWidget(): Widget

abstract class Widget
+ config()

class StatsDashboard extends Dashboard
+ createWidget: Widget -> return new StatsWidget()

class StatsWidget extends Widget

Вызов createWidget () возвращает виджет, но какой конкретный виджет для возврата должен быть отложен до подклассов (StatsDashboard возвращает StatsWidget).

Обратите внимание, что методы создания объявленывверх по дереву наследования, но они выполняются по дереву наследования.

reader Читатель с острым взглядом увидит, что абстрактные фабричные методы напоминают фабричные методы, совпадение?- нетИменно здесь и происходит имя фабричного метода (они выполняют конкретную реализацию класса).

Допущена путаница с «фабриками в США»;это плохой выбор слов.Автор намекает, что этот код может быть передан фабричным рабочим, что совершенно не имеет значения и вводит в заблуждение относительно фабричных шаблонов.


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

public function createToy($toyName) {
    $toy = null;

    if ('car'==$toyName) {
        $toy = new NyCar();//I'm a Toy
    } else if ('helicopter'==$toyName) {
        $toy = new NyHelicopter();//I'm a Toy
    }

    return $toy;
}

Используя полиморфизм, мы можем удовлетворить принцип открытого-закрытого, создав набор классов-братьев:

abstract class Toy
+ operate()

Car extends Toy
Helicopter extends Toy

some_toy.operate();

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

Внедрение зависимостей следует использовать для создания конкретной игрушки.

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

...