преимущество иметь фабрику для создания объекта?

Я пытаюсь понять шаблон проектирования фабрика.

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

пример с завода:

$mac = new Mac();

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

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

как картина фабрики отделяет клиента от продукта?

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

спасибо.

3 ответов


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

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

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

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

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


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


в этом примере возвращается объект типа 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 заявление. И у вас может быть несколько таких!--11--> операторы в других частях вашего приложения.

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

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