Я читаю о фабричном методе и простой фабрике. Получается Как я понимаю, простой фабрики достаточно, и я не вижу варианта использования шаблона фабричного метода. Пожалуйста, прочитайте эту ссылку, 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 () может
инкапсулировать создание объекта и, поскольку оно абстрактно, оно делегирует
создание его подклассов.
Вопрос заключается в следующем: а) что это значит, говоря о передаче его фабрикам США? б) или мы не хотим, чтобы филиалы в США могли модифицировать функции yieldToy (). они все еще могут модифицировать функцию yieldToy, какая разница, если они не могут или могут ее изменить? Я просто не понимаю, почему простая фабрика была плоха для следующего примера.
Не нужно читать об абстрактной фабрике по этой ссылке
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 () возвращает Widget, но какой конкретный Widget должен быть возвращен подклассам (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();
Добавление к случаям переключения — не что иное как создание другого родственного класса.
Внедрение зависимости следует использовать для создания конкретной игрушки.
Надеюсь, это поможет!
Других решений пока нет …