Можно ли заменить синглтон на Factory?

Уже есть довольно много сообщений о Singleton-Pattern, но я хотел бы начать еще одну по этой теме, так как я хотел бы знать, будет ли Factory-Pattern правильным подходом для удаления этого «антипаттерна».

Раньше я довольно часто использовал синглтон, как и мои коллеги, так как он очень прост в использовании. Например, Eclipse IDE или лучше ее рабочая среда также интенсивно используют синглтоны. Это произошло из-за некоторых сообщений о E4 (следующей большой версии Eclipse), которые заставили меня переосмыслить синглтон.

Суть в том, что из-за этих синглтонов зависимости в Eclipse 3.x сильно связаны.

Предположим, я хочу полностью избавиться от всех синглтонов и вместо этого использовать фабрики.
Мои мысли были следующими:

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

Имеет ли это смысл? Если нет, пожалуйста, объясните, почему вы так думаете. Также приветствуется альтернативное решение.

Спасибо

Марк


person lostiniceland    schedule 04.05.2010    source источник
comment
Я до сих пор не понимаю, как сравнивать эти два паттерна. Насколько я понимаю, оба они полностью разделены (за исключением того, что они относятся к одной и той же категории - Creational Patterns   -  person SysAdmin    schedule 04.05.2010
comment
В этом мире есть нечто большее, чем одни лишь образцы.   -  person Dykam    schedule 04.05.2010
comment
Я имею в виду, попытка трансформировать один базовый паттерн в другой базовый паттерн ... это звучит как чрезмерно шаблонный ум.   -  person Dykam    schedule 04.05.2010
comment
Спасибо за все ответы и ссылки. @SysAdmin: верно, это шаблоны создания, поэтому они предоставляют вам ссылки на объекты. Поскольку синглтон все чаще называют анти-шаблоном, я спрашивал, можно ли использовать фабрику для целей, в которых я использовал синглтон в прошлом.   -  person lostiniceland    schedule 04.05.2010


Ответы (6)


Я согласен, что иногда это имеет смысл. Однако это зависит от того, что вы создаете.

Если вы замените каждый синглтон на фабрику только потому, что он «лучше», вы делаете это неправильно, imho. Это должно служить определенной цели. Если вы не собираетесь издеваться, если вы уверены, что вам нужен только один экземпляр и т. Д., То замена - это просто «архитектурная маструбация»;)

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

person Henri    schedule 04.05.2010
comment
Поскольку есть 3 ответа с 2 положительными голосами, было сложно выбрать, какой из них лучший. Я решил отметить этот как правильный из-за предупреждения о чрезмерном использовании шаблонов только по архитектурным причинам. - person lostiniceland; 09.05.2010

На мой взгляд, основным недостатком синглтонов является тесная связь (со всеми вытекающими последствиями, такими как плохое тестирование и т. Д.).

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

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

person Eric Eijkelenboom    schedule 04.05.2010

Насколько я понимаю, вы не можете «заменить» Singleton на Factory, но вы можете использовать эти шаблоны вместе. Factory вернет экземпляр объекта вызывающей стороне метода Factory. Если вы хотите убедиться, что существует только один экземпляр определенного объекта, который возвращает Factory, тогда этот объект должен быть синглтоном. Вы прячете синглтон на фабрике.

Если вы храните частный экземпляр объекта в Factory, а не в самом объекте - тогда как вы можете обеспечить, чтобы в системе всегда был только один экземпляр объекта? Как вы можете добиться, чтобы этот объект создавался только вашей фабрикой?

Вы можете заменить синглтон на IoC, и действительно, похоже, есть много плохих предчувствий к синглтону как к антипаттерну, и даже Гамма сказал, что ему жаль, что он не исключил его из книги GoF ...

person Peter Kelly    schedule 04.05.2010
comment
Хорошие моменты. Что касается ваших соображений, как убедиться, что существует только один экземпляр класса, когда я помещаю частный экземпляр в свой Facroty: я бы сделал пакет объектов частным, чтобы его мог вызывать только Factory в этом пакете. Конечно, это работает только с закрытым исходным кодом. В команде разработчиков я бы должным образом задокументировал это, но вы правы ... технически не гарантируется, что существует только один экземпляр. Но так бывает, когда вы используете шаблон singleton в среде OSGi, поскольку каждый пакет имеет свой собственный загрузчик классов (просто чтобы упомянуть об этом) - person lostiniceland; 04.05.2010
comment
Интересный момент по поводу OSGi-окружения - я об этом не думал. - person Peter Kelly; 04.05.2010
comment
Прочитав это, я нашел несколько интересных ссылок tech.jayasoma.org/2008/12/ stackoverflow.com/questions/1318856/ - person Peter Kelly; 04.05.2010
comment
Но его только делает пакет одноэлементным. В OSGi вы можете одновременно запускать несколько пакетов одного типа. Директива singleton просто избегает этого. Чтобы получить один загрузчик классов для нескольких пакетов, вы можете использовать buddy-policy. Мне пришлось использовать это один раз для гибернации. Но это больше похоже на обходной путь при использовании фреймворка, который не предоставляется в виде пакета и не предназначен для исправления некоторых проблем с загрузкой классов с использованием одноэлементного шаблона :-) - person lostiniceland; 05.05.2010

Factory - определенно альтернатива Синглтону, и я бы предпочел первый второму. Синглтоны очень сложно тестировать и приводят к сильной связи. Фабрики, если они правильно реализованы (с использованием чистых интерфейсов и т. Д.), Приводят к более тестируемому коду и меньшему количеству взаимосвязей.

Тем не менее, это не означает, что вы должны использовать фабрики как кувалду для решения каждой проблемы. Существуют и другие шаблоны, которые также могут привести к меньшей связанности, чем Singleton, но являются более подходящим решением. Например: инверсия управления.

person RationalGeek    schedule 04.05.2010
comment
Лично я считаю, что шаблон ServiceLocator гораздо более поддается замене на Singleton, чем Factory. Мартин Фаулер обсуждает эту тему: martinfowler.com/articles/injection.html#UsingAServiceLocator - person LBushkin; 18.05.2010
comment
Подобно синглтону, Service Locator сам по себе считается анти-шаблоном, поэтому я не думаю, что это должен быть маршрут. - person Moss; 05.10.2011

Синглтоны, описанные в шаблоне проектирования, обычно используют статические переменные, что затрудняет тестирование кода.

Я бы рекомендовал прочитать это от Мишко Хевери и две последующие статьи 1 и 2. Здесь он описывает, в чем разница между объектом с одним экземпляром и объектом Singleton, как в шаблоне проектирования, и что предпочтение следует отдавать первому из них.

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

person MKroehnert    schedule 04.05.2010
comment
Спасибо за ссылку. Я действительно наткнулся на этот пост некоторое время назад, но потом я потерял ссылку (я вспомнил только первые моменты). - person lostiniceland; 04.05.2010

Синглтон, конечно, антипаттерн. А если вы используете TDD - вам следует избегать таких решений. Любая инфраструктура IoC, такая как Windsor или Unity, может эмулировать эту функциональность без ужасных статических классов. Однако, если вы не используете TDD и ваш проект довольно прост, вы можете его использовать. Кстати, я бы порекомендовал IoC Framework, а не самодельные фабрики. Не изобретайте колесо.

person Voice    schedule 04.05.2010
comment
Да, я стараюсь использовать TDD в максимально возможной степени, но все же стараюсь сохранять то количество, которое собирается IoC, на умеренной скорости (компонентный состав). Сторонники Spring всегда заявляют, что с его помощью вы пишете так мало кода, но они забывают упомянуть огромные файлы xml :-) - person lostiniceland; 04.05.2010
comment
Что ж, могу сказать, что Spring - не лучшее решение IoC для .NET. Это мощно, но неудобно. Особенно из-за ужасного конфига. Попробуйте Windsor или Unity - намного лучше) - person Voice; 05.05.2010