Одиночный / фабричный метод, который вы описываете, функционален и прост в реализации. Но синглтоны опасны, потому что, если вы захотите внедрить варианты ваших услуг в области юстики в будущем, вам, возможно, придется реорганизовать вещи, чтобы приспособить их. Кроме того, синглтоны обычно передаются на статических фабриках, которые сами по себе могут мешать расширению.
Вместо одноэлементного / факторного подхода рассмотрим внедрение зависимостей. Это более громоздко для реализации, но расширяется более изящно.
С внедрением зависимостей вы прогнозируете потребности компонентов в данных / сервисах, передавая их зависимым компонентам до того, как они понадобятся. (В то время как альтернатива оставляет работу по поиску этих данных / службы для этого компонента - функциональность, которую вы могли бы достичь с помощью чего-то вроде статической фабрики.) В общем, вы удаляете компоненты из пары и изолируете их функциональность; это обычно считается эффективным подходом к проектированию.
В качестве более конкретного примера, вместо того, чтобы ваши сервлеты вызывали com.me.Herusitic#getInstance()
, они вместо этого имели бы экземпляр Heuristic
, передаваемый их конструкторам. Эта ссылка Heuristic
сохраняется внутри объекта и вызывается по мере необходимости. Позже, когда вы расширили Heuristic
до FancyHeuristic
и FakeHeuristicForTesting
и хотите, чтобы ваши сервлеты использовали их вместо этого, вам не нужно изменять код сервлета: просто введите новый тип эвристики. При заводском подходе вам придется переписать свою заводскую логику.
Этот ответ только царапает поверхность этой темы. К счастью, нет конца обсуждению шаблона проектирования DI (как в StackOverflow, так и в других местах), поэтому я предоставлю вам возможность продолжить исследования.