Я читаю о шаблоне фабричного метода и простой фабрике. Как я понимаю, простой фабрики достаточно, и я не вижу варианта использования паттерна фабричного метода. Прочтите эту ссылку, 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;
}
}
Затем он говорит:
The developers finish the new code quickly and hand it over to the US factories. After two weeks, the phone starts ringing in the developers’ office because the New York factory was having production issues. It turns out that the NyToysFactory class has been modified by developers at the remote branch because the staff doesn’t want to do packaging and labeling work. They’ve modified produceToy() by removing its label() and package() functions.
It seems like Simple Factory won’t work in this scenario. We don’t want branches in US to be able to modify produceToy() functions. ProduceToy() should consist of a set of standard procedures and the branches should only be responsible for creating location specific toys. What if they can create an abstract class? And the abstract class they create will have a concrete produceToy()method which will implement a set of standard operating procedurea that all branches have to follow. Inside produceToy(), it calls its own abstract method createToy() to obtain a toy class. This way createToy() is able to encapsulate object creation and, since it’s abstract, it delegates the creation to its subclasses.
Вопрос: а) Что это значит, когда говорится о передаче фабрики в США? б) или Мы не хотим, чтобы филиалы в США могли изменять функции produToy (). они все еще могут изменять функцию produToy, какая разница, если они не могут или могут ее изменить? Я просто не понимаю, почему простая фабрика вообще была плохой для следующего примера.
Не нужно читать об абстрактной фабрике по этой ссылке






ТHIS CODE / PROBLEM не освещает абстрактную фабрику или фабричный метод. Решение, какой класс создать, включив параметр, действительно является анти-паттерном, поощряющим нарушение принципа открытого-закрытого.
Абстрактная фабрика
Абстрактная фабрика - это все о применении семья связанных классов:
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) - в этом сила Abstract Factory.
Notice the products, bears, elephants, etc., are known AoT (ahead of time).
Заводской метод
Фабричный метод заключается в том, чтобы отложить создание экземпляров до подклассов.
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).
Notice the creation methods are declared up the inheritance tree, but they are fulfilled down the inheritance tree.
❧ Внимательный читатель увидит, что методы абстрактной фабрики похожи на методы фабрики, совпадение? - нет. Отсюда происходит название фабричного метода (они выполняют создание конкретного класса).
Путаница относительно «заводов в США» верна; это плохой выбор слов. Автор намекает, что этот код может быть передан заводским рабочим, что совершенно не имеет отношения к заводским шаблонам и сбивает с толку.
Чтобы разрешить описанный выше переключатель, вам необходимо осознать очевидное: каждый обработчик условий каким-то образом связан. В данном случае это все игрушки.
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();
Добавление к корпусам переключателей - это не что иное, как создание еще одного родственного класса.
Надеюсь, это поможет!
Фабричный метод заключается в том, чтобы отложить создание экземпляров до подклассов. Это важно, когда вы создаете интерфейсы, которые создают объекты, но не можете предсказать, какие объекты будут созданы.
Можем ли мы обсудить это в приватном чате или что-то в этом роде? Я многое узнал об этом шаблоне, но все еще меня как-то смущает. Вопросы, которые у меня есть, займут здесь много времени. заранее спасибо
Итак, вместо того, чтобы использовать switch (if/else) и позволить createToy выбрать подкласс, мы должны передать подкласс в качестве аргумента и просто позволить createToy создать его экземпляр?
@Rafael Если фабричный метод полагается на DI вместо некоторого параметра, переданного переключателю, как в простой фабрике, как он используется в качестве фабрики, которая может производить различные продукты во время выполнения? Разве фабричный метод никогда не использует переключатель или некоторую управляющую логику, чтобы решить, какой гордый продукт или создатель продукта создать? Если это похоронено в контейнере DI, как бы вы могли заставить этот контейнер возвращать разные типы экземпляров для одного и того же интерфейса?
@ ΕГИІИО Я удалил оператор DI, так как он сбивал с толку. Однако фабричный метод знает, какой продукт создать, просто вызывая его через одну отправку.
@ ΕГИІИО Да, клиенту потребуется управляющая логика, чтобы решить, какой класс (с фабричным методом) создать, но эта управляющая логика абсолютно не должна присутствовать ни в каких фабричных методах. Это противоречит цели шаблона проектирования.
@Rafael Хм, если я правильно понял, когда вы реализуете фабричный метод, вам все равно понадобится простая фабрика (или подобный код) на клиенте, чтобы раскрутить вещи. Вы встречали какой-нибудь образец кода, показывающий это подключение? наверное без части DI? Фабричный метод меня каждый раз сбивает с толку.
@ ΕГИІИО Именно. Имейте в виду, что это всего лишь пример полиморфизма и не более того. Это просто обычный случай использования полиморфизма, достойный названия. Основная идея полиморфизма состоит в том, чтобы код был универсальным, а значит, можно было использовать повторно, чтобы клиентам не нужно было знать, с чем они работают. Это позволяет нам использовать доводить до клиентов конкретные решения, чтобы в итоге мы получили «общее ядро» и «небольшую конкретную оболочку» (являющуюся неуниверсальным аспектом кода).
@ ΕГИІИО Вам, В самом деле, нужно значительное общее ядро; это означает, что вы получаете много повторного использования. Кроме того, общий код можно извлечь в библиотеку. Я сомневаюсь в коде, который имеет толстую одноразовую оболочку, потому что, давайте посмотрим правде в глаза, большая часть кода делает то же самое (более или менее), и редко что-то отличается от тот.
@ ΕГИІИО Тем не менее, это не означает, что все, что может быть общим, должно быть универсальным. Это привело бы к ненужному увеличению сложности, т. Е. К чрезмерной инженерии. Это зависит от цели, предметной области и варианта использования, например, что может измениться со временем, и т. д. И т. Д. ... Большинство абстракций лучше отложить до времени, в котором они необходимы, т. Е. Вводить органически, по запросу. , а не с нетерпением.
Спасибо, Рафаэль. Мы поговорим о разнице между фабричным методом и простой фабрикой. Я могу делать что угодно с простой фабрикой, зачем вообще использовать фабричный метод?