Преимущество наличия фабрики для создания объектов? - PullRequest
6 голосов
/ 24 апреля 2010

Я пытаюсь понять шаблон фабричного дизайна.

Я не понимаю, почему хорошо иметь посредника между клиентом и продуктом (объектом, который хочет клиент).

пример без фабрики:

$mac = new Mac();

пример с фабрикой:

$appleStore = new AppleStore();
$mac = $appleStore->getProduct('mac');

Как фабричный шаблон отделяет клиента от продукта?

Может ли кто-нибудь привести пример будущего изменения кода, которое повлияет на пример 1 отрицательный, но положительный в примере 2, поэтому я понимаю важность развязки?

Спасибо.

Ответы [ 3 ]

5 голосов
/ 24 апреля 2010

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

Неофициально, если вы скажете кому-нибудь создать Mac, это будет кропотливый процесс, который займет годы проектирования, разработки, производства и тестирования, и, возможно, это будет сделано неправильно. Этот процесс должен быть повторен для каждого Mac. Однако, если вы вводите фабрику, всю тяжелую работу можно выполнить всего один раз, тогда Mac можно производить дешевле.

Теперь рассмотрим factory.php Joomla . Из того, что я могу сказать, основная цель JFactory - объединить объекты и убедиться, что объекты, которые должны быть одинаковыми, не копируются. Например, JFactory::getUser() вернет ссылку на один и только один объект. Если что-то изменилось в этом пользовательском объекте, оно появится везде. Также обратите внимание, что JFactory::getUser() возвращает ссылку, а не новый объект. Это то, что вы просто не можете сделать с конструктором.

Часто при создании объекта вам необходим локальный контекст, и этот контекст может сохраняться и принимать различные формы. Например, может быть база данных MySQL, содержащая пользователей. Если объекты User создаются с помощью конструктора, вам необходимо передать объект Database в конструктор (или использовать его для глобальной переменной). Если вы решите переключить свое приложение на PostgreSQL, семантика объекта Database может измениться, что потребует пересмотра всех применений конструктора. Глобальные переменные позволяют нам скрывать эти детали, как и фабрики. Таким образом, фабрика User будет отделять детали построения объектов User от мест, где необходимы объекты User.

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

2 голосов
/ 24 апреля 2010

Не знаю, смогу ли я сказать это лучше, чем IBM https://www.ibm.com/developerworks/library/os-php-designptrns/#N10076

1 голос
/ 24 апреля 2010

Этот пример возвращает объект типа Mac, и он никогда не может быть чем-то другим:

$mac = new Mac();

Это не может быть подкласс Mac, не может быть классом, который соответствует интерфейсу Mac.

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

$appleStore = new AppleStore();
$mac = $appleStore->getProduct('mac');

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

Таким образом, фабрика дает вам больше гибкости в создании объектов. Гибкость часто идет рука об руку с развязкой.


Re ваш комментарий: я бы не сказал никогда использовать new. На самом деле, я использую new для создания большинства простых объектов. Но это не имеет никакого отношения к тому, кто пишет код клиента. Фабричный шаблон предназначен для случаев, когда вам нужна архитектура, которая может выбирать класс для динамического создания экземпляра.

В вашем примере с Apple Store вам, вероятно, понадобится простой код для создания экземпляра продукта и его добавления в корзину. Если вы используете new и у вас есть разные типы объектов для каждого типа продукта, вам нужно написать огромный оператор case, чтобы вы могли создать new объект соответствующего типа. Каждый раз, когда вы добавляете тип продукта, вам придется обновлять этот оператор case. И у вас может быть несколько таких case утверждений в других частях вашего приложения.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...