Отличается ли шаблон Service Locator от шаблона Abstract Factory?

На первый взгляд, паттерн Service Locator мне кажется таким же, как паттерн Абстрактная фабрика. Кажется, что они оба имеют одинаковое использование (вы запрашиваете их для получения экземпляров абстрактных сервисов), и они оба были упомянуты, когда я читал о внедрении зависимостей.

Однако я видел, что шаблон Service Locator описан как плохая идея, но видели прямую поддержку шаблона Абстрактная фабрика в по крайней мере, один основной фреймворк для внедрения зависимостей.

Если они не совпадают, в чем разница?


person Merlyn Morgan-Graham    schedule 18.04.2011    source источник
comment
возможный дубликат инъекции зависимостей и фабричного шаблона   -  person Juliet    schedule 18.04.2011
comment
@Juliet: Ни локатор служб, ни абстрактная фабрика не являются внедрением зависимостей. DI - это выталкивающая модель, тогда как фабрики и локаторы сервисов - вытягивающая модель. И да, я предпочитаю DI + IoC локатору сервисов - я просто хочу понять Service Locator. Я не против, чтобы был найден фактический дубликат, тем не менее :) Можете ли вы повторно добавить то сообщение в блоге, которое вы оставили перед редактированием?   -  person Merlyn Morgan-Graham    schedule 18.04.2011
comment
Вот и все: kill-0.com/duplo/2010/02/05/. Кажется, вы не единственный, кто задается вопросом, чем отличаются паттерны Service Locator и Abstract Factory :)   -  person Juliet    schedule 18.04.2011


Ответы (4)


Я наткнулся на тот же вопрос, исследуя эти закономерности. Я думаю, что основные различия можно найти между Service Locator и Factory (абстрактно это или нет):

Поиск услуг

  • «Обнаруживает» существующую зависимость (службу). Хотя услуга может быть создана во время разрешения проблемы, она не имеет значения для Клиента, потому что:
  • Клиент локатора служб НЕ принимает права собственности на зависимость.

Фабрика

  • Создает новый экземпляр зависимости.
  • Клиент фабрики становится владельцем зависимости.

Абстрактная фабрика

  • То же, что и обычная Factory, за исключением того, что разные развертывания могут использовать разные реализации абстрактной фабрики, позволяя создавать экземпляры разных типов в этих разных развертываниях (вы даже можете изменить реализацию абстрактной фабрики во время выполнения, но обычно это не так, как она используется).
person Gyan aka Gary Buyn    schedule 22.02.2012
comment
+1; Хороший момент в том, что цель отличается. Я предположил, что это будет очевидно по названиям паттернов, поэтому я сосредоточился на механике и общедоступном интерфейсе, а не на намерении использовать. Это различие очень важно с точки зрения жизненного цикла объектов, возвращаемых двумя классами. - person Merlyn Morgan-Graham; 23.02.2012
comment
Я думаю, что намерение - это определяющая характеристика паттерна. Например, декоратор и прокси могут быть реализованы одинаково, но у них разные цели. - person Gyan aka Gary Buyn; 23.02.2012
comment
Принимаю ваш ответ в пользу моего, потому что цель шаблона более важна, чем то, как интерфейс поддерживает это намерение. - person Merlyn Morgan-Graham; 31.03.2013
comment
Приведите образцы кода, подтверждающие то, что вы сказали. Было бы намного легче понять - person Adi; 26.06.2018

Из того, что я прочитал до сих пор, я думаю, разница в следующем:

Шаблон Service Locator

  • Явно поддерживает регистрацию того, какие конкретные объекты должны быть созданы / возвращены
  • Обычно имеет общий интерфейс, позволяющий пользователю запрашивать любой абстрактный тип, а не конкретные типы.
  • Сам может быть конкретным

Шаблон "Абстрактная фабрика"

  • Может не поддерживать регистрацию - это зависит от конкретной реализации, которая будет поддерживать или не поддерживать, и, вероятно, не будет отображаться в абстрактном интерфейсе
  • Обычно имеет несколько методов получения для определенных абстрактных типов.
  • Не является сам по себе конкретным (хотя, конечно, будет иметь конкретные реализации)
person Merlyn Morgan-Graham    schedule 18.04.2011
comment
Я не уверен в своем ответе, потому что у меня нет большого опыта работы с шаблоном Service Locator. Если кто-то хочет дать более осознанный ответ, не стесняйтесь. - person Merlyn Morgan-Graham; 25.04.2011
comment
Теперь мне гораздо удобнее пользоваться этими концепциями. Мой ответ правильный, но это половина дела. Намерение важнее. См. Другой ответ на вопрос - stackoverflow.com/a/9403827/232593 (также: я рекомендую не использовать DI контейнер, за исключением реализации архитектуры плагина. Используйте ручной ввод конструктора внутри границ вашего приложения, с фабриками, где они вам нужны. Создайте дерево объектов в основном или собственном модуле. Используйте Service Locator для подключения к действительно ненадежной службе, а не к процессу / системе ваша программа будет владеть и полностью контролировать ее наличие). - person Merlyn Morgan-Graham; 26.09.2016

На самом деле между этими двумя паттернами есть четкое разделение. Общеизвестно, что оба шаблона используются, чтобы избежать зависимости от конкретных типов.

Однако после прочтения

  • Гибкая разработка программного обеспечения, принципы, шаблоны и практики [книга] Робера К. Мартина
  • Инверсия управляющих контейнеров и шаблон внедрения зависимостей [статья] Мартина Фаулера на http://martinfowler.com/articles/injection.html
  • Распознавание образов: абстрактная фабрика или локатор услуг? [статья] Марка Зеемана на http://blog.ploeh.dk/2010/11/01/PatternRecognitionAbstractFactoryorServiceLocator/
  • Шаблон дизайна [книга] Эриха Гаммы и др.

Возникают серьезные противоречия:

Земанн сказал: «Абстрактная фабрика - это универсальный тип, и тип возвращаемого значения метода Create определяется типом самой фабрики. Другими словами, сконструированный тип может возвращать только экземпляры одного типа».

В то время как Робер К. Мартин ничего не упомянул об общих типах и, более того, пример фабрики в своей книге позволяет создавать экземпляры более одного типа объектов, различать их, используя ключевую строку в качестве параметра в Factory.Make ().

Гамма сказал, что цель Abstract Factory состоит в том, чтобы «предоставить интерфейс для создания семейств связанных или зависимых объектов без указания их конкретных классов». Стоит упомянуть, что пример Gamma Abstract Factory нарушает принцип разделения интерфейса (ISP), заявленный Мартином. ISP и SOLID в целом являются более современными принципами или, возможно, для простоты они опущены.

Работы Гаммы и Мартина предшествуют работам Симана, поэтому я думаю, что он должен следовать уже данному определению.

В то время как Фаулер предлагает Service Locator как способ реализации инверсии зависимостей, Зееманн рассматривает его как анти-шаблон. Ни Гамма, ни Мартин не упоминают Service Locator.

Однако Земанн и Фаулер согласились с тем, что локатору служб требуется этап конфигурации для регистрации экземпляра конкретного класса, этот экземпляр будет возвращен позже, когда будет запрошен объект такого типа. Этот шаг настройки не упоминается Мартином или Гаммой в их определении Abstract Factory. Шаблон «Абстрактная фабрика» предполагает, что новый объект создается каждый раз, когда запрашивается объект такого типа.

Заключение

Основное различие между Service Locator и Abstract Factory состоит в том, что Abstract Factory предполагает, что новый объект создается и возвращается при каждом запросе, а Service Locator должен быть настроен с экземпляром объекта, и каждый раз будет возвращаться один и тот же экземпляр.

person jfuentes    schedule 08.02.2015
comment
Я согласен с тем, что понятие абстрактной фабрики, предложенное Симаном, не соответствует определению GoF; но почему вы говорите, что определение GoF нарушает ISP? Намерение состоит в том, чтобы каждый клиент использовал все фабричные методы. - person jaco0646; 09.08.2016

От: http://blog.ploeh.dk/2010/11/01/PatternRecognitionAbstractFactoryorServiceLocator/

Абстрактная фабрика - это универсальный тип, и тип возвращаемого значения метода Create определяется типом самой фабрики. Другими словами, сконструированный тип может возвращать только экземпляры одного типа.

С другой стороны, Service Locator - это неуниверсальный интерфейс с универсальным методом. Метод Create одного локатора сервисов может возвращать экземпляры бесконечного числа типов.

person John Smith    schedule 06.03.2016