Фабричный шаблон - CreateInstance статический или нет? - PullRequest
31 голосов
/ 27 октября 2011

Это о фабричном образце.Я немного запутался.

Я видел реализации, в которых метод createInstance() является статическим, а некоторые реализации не являются статичными.

Некоторые говорят, что это зависит от "стиля" или "вкуса"а некоторые говорят, что нет.Википедия говорит, что он должен быть нестатичным, а http://www.dofactory.com/Patterns/PatternFactory.aspx также говорит, что он должен быть нестатичным, в соответствии с Бандой четырех.

Мой вопрос: зависит ли это от стиля ивкус или это нарушает фабричный шаблон, если он реализован статическим способом?Что правильно?

Ответы [ 3 ]

43 голосов
/ 27 октября 2011

Я очень не решаюсь классифицировать «экземпляр против статики» как вопрос вкуса.Этот вид подразумевает, что он эстетичен, как любимый цвет или, более подходящие, camelCase и PascalCase.

Экземпляр и статика - это скорее вопрос компромиссов.С экземплярами любого типа вы получаете все преимущества полиморфизма, поскольку вы можете реализовать интерфейсы и наследовать от других классов, когда у вас есть экземпляры и члены экземпляра.С помощью статики вы не получите этих преимуществ.Как правило, статический по сравнению с экземпляром - это компромисс между простой простотой и простотой ниже по потоку.Статика проста, потому что она доступна во всем мире, и вам не нужно рассматривать такие вещи, как «когда это должно быть создано и кем?»Вам не нужно передавать их с помощью аксессоров / мутаторов или конструкторов, и ваш API выглядит чище.Это упрощает рассуждения.Но это усложняет обслуживание и будущие реализации.

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

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

Мой совет заключается в том, чтобы в будущем вы и / или другие сопровождающие оказали услугу ииспользуйте реализацию экземпляра.Дело не в том, что Банда Четырех или кто-либо другой хочет или предпочитает - это вопрос вашего собственного здравомыслия перед лицом гниения кода.

18 голосов
/ 27 октября 2011

Статический метод не нарушает шаблон, но он идет вразрез со многими другими объектно-ориентированными практиками (инверсия управления + внедрение зависимостей в качестве одного примера), поэтому лучше использовать экземпляры.

Edit:

Я только получил значок для этого ответа, но когда я прочитал его, я не мог поверить своим глазам. Неверно, когда мы строго говорим о шаблоне метода GoF Factory, и он заслуживает некоторого исправления.

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

Смысл шаблона метода GoF Factory - заменить условную логику внутри CreateInstance наследованием и полиморфизмом, и, следовательно, она не может быть статической. Фабричный метод - это метод экземпляра, причем виртуальный. Ваш базовый тип обычно имеет абстрактный CreateInstance, и условная логика заменяется деревом наследования, где каждый подтип переопределяет CreateInstance и создает только конкретный продукт для этого подтипа.

7 голосов
/ 27 октября 2011

Если это abstract factory, то уровень экземпляра нормальный.А функциональность на уровне экземпляра, как правило, легче имитировать и тестировать, чем static level

...