миф о [закрытом] шаблоне "фабрика"

8
задан Madara Uchiha 5 April 2012 в 17:12
поделиться

5 ответов

Если пользователь известен только в то время, когда создается заказ, вы можете реализовать функцию getCurrentUser () , которая вызывается фабрикой.
Если это возможно, очевидно, что заводская функция выигрывает. Если нет, то выигрыша нет.

Если в прошлом вы не знали, что потребуется клиент, вы, вероятно, также не могли знать, возможно ли реализовать функцию getCurrentUser () . Шансы на то, что заводской метод окупится, могут быть не очень хорошими, но они не всегда равны 0.

5
ответ дан 5 December 2019 в 14:01
поделиться

Нет, потому что зависимость для фабрики должна быть введена через конструктор фабрик, и вы конструируете фабрику только в одном месте, но передаете ее как зависимость от всего, что необходимо для создания заказа. То, что получает заказы от фабрики, по-прежнему вызывает один и тот же метод CreateOrder () или что-то еще, и поэтому этот код не изменяется.

Все зависимости должны быть связаны в одном месте, корневая структура , и это должно быть единственное место, которое необходимо изменить, чтобы добавить новую зависимость в фабрику

{{ 1}}
2
ответ дан 5 December 2019 в 14:01
поделиться

Шаблон фабрики может облегчить боль, связанную с добавлением зависимости, потому что фабрика может содержать состояние и, фактически, может инкапсулировать несколько зависимостей ( например, вместо предоставления трех зависимостей, необходимых для вызова конструктора какого-либо объекта, теперь вы предоставляете только один объект фабрики, где фабрика содержит те три объекта, которые необходимо предоставить конструктору).

Чтобы дать пример, сравните:

void DoIt(const DependencyA& a, const DependencyB& b) {
   // NOTE: "x" is a contrived additional variable that we add here to
   // justify why we didn't just pass DependencyC directly.
   int x = ComputeX(); 
   std::unique_ptr<DependencyC> dependency_c(new DependencyC(a, b, x));
   dependency_c->DoStuff();
}

И:

void DoIt(const DependencyCFactory& factory) {
  int x = ComputeX();
  std::unique_ptr<DependencyC> dependency_c(factory->Create(x));
  dependency_c->DoStuff();
}

Обратите внимание, что вторая версия требовала меньшего количества зависимостей от метода «DoIt». Это не означает, что эти зависимости не нужны во всей программе (действительно, программа по-прежнему использует DependencyA и DependencyB в реализации фабрики).Однако, структурируя его таким образом, эта зависимость может быть изолирована только от заводского кода, что упрощает другой код, упрощает изменение зависимостей DependencyC (теперь только сама фабрика должна быть быть обновленным, а не каждое место, где создается DependencyC ), и даже может иметь определенные преимущества безопасности (например, если DependencyA и DependencyB являются конфиденциальными, например пароли базы данных или ключи API, ограничивая их использование фабрикой, снижает вероятность неправильного обращения по сравнению со случаями, когда вы передаете их везде, где вам нужно использовать базу данных или API, например).

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

1
ответ дан 5 December 2019 в 14:01
поделиться

Вы сообщаете фабрике о новой зависимости и позволяете ей добавить ее за вас. Вызов метода фабрики не должен быть изменен.

1
ответ дан 5 December 2019 в 14:01
поделиться

Реальное преимущество использования Factory состоит в том, что это фасад, который скрывает то, как вы собираетесь создавать объект, выполняющий роль Order. Точнее, Factory знает, что вы действительно делаете FooBarOrder, и больше ничего не нужно менять, чтобы переключиться с постоянного создания FooBarOrder на иногда вместо этого BarFooOrder. (Если Java позволит вам перехватить new и вместо этого создать подкласс, то фабрики не понадобятся. Но это не так - справедливо, если честно, - поэтому вы должны иметь их. Объектные системы, которые позволяют создавать подклассы, классы классов более гибкие в этом отношении.)

3
ответ дан 5 December 2019 в 14:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: