2010-04-24 6 views
6

Я пытаюсь понять шаблон дизайна завода.Преимущества создания фабрики для создания объекта?

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

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

$mac = new Mac(); 

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

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

Как шаблон завода разъединить клиент от продукта?

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

Спасибо.

+1

Этот второй кажется скорее отношением, а не фабрикой для меня ...? – SeanJA

ответ

5

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

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

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

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

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

+1

+1 аналог бонус – SeanJA

+0

, но это не называется «перемещение процесса в центральное место». что я не понимаю, это слово «развязка». –

+0

, но если мне нужно изменить базу данных и им использовать фабрику, мне все равно придется менять свой код на заводе. это эта часть, которую я не совсем понимаю. в любом случае я должен измениться, теперь я просто перевел его в другой класс, на фабрику. я могу понять, что это хорошо, если вы имеете дело с приложениями frameworks/os. ваши пользователи, взаимодействующие с вашим кодом, не должны переписывать свой код. но если я единственный, кто использует код, который я пишу, как лучше завод? Мне все равно придется менять, если я меняю базу данных. –

1

Этот пример возвращает объект типа 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 в простых случаях.

+0

поэтому основное внимание уделяется «как я могу написать код, поэтому всякий раз, когда я меняю код MY, у КЛИЕНА не обязательно»? поэтому в принципе я НИКОГДА не хочу, чтобы клиент использовал новые на «конечных продуктах». Я хочу предоставить слой абстракции (фабрики) для создания продуктов. поэтому он не должен знать, что происходит за кулисами? я прав? но как насчет того, когда я сам все кодирую? в любом случае, я должен измениться. я не совсем понимаю, где находится фокус или что я как разработчик хочу сделать. –

Смежные вопросы