Сервисный локатор против внедрения зависимостей - PullRequest
5 голосов
/ 09 июня 2011

Я рассматриваю код с большим количеством утверждений, подобных этому:

private SomeInterface x = Locator.getInstance(SomeInterface.class)

Я бы ожидал что-то вроде

private SomeInterface x;

@Inject
public Consumer(SomeInterface x){ // constructor
    this.x = x;
}

Что-то не так с первым подходом?Хорошо, зависимости не так очевидны, но реализации можно легко поменять местами с помощью конфигурации Locator.

Ответы [ 4 ]

10 голосов
/ 09 июня 2011

Мартин Фаулер написал статью о DI против локаторов :

Для DI:

  • Проще определить, какие зависимости у компонента - смотритеat constructor.
  • Компонент не зависит от Service Locator, поэтому не возникает проблем, если компонент используется с другой структурой.
  • DI может упростить тестирование, но хороший механизм Service Locatorсделает заглушку одинаково осуществимой.

Лично я не думаю, что с первым подходом, основанным на локаторе, есть что-то изначально плохое - я думаю, что DI действительно стандартизирует это, поэтому, если оно доступно, я бы использовал его.Все хорошие идеи в какой-то момент становятся основой, так что вот что здесь произошло.Кроме того, с помощью DI вы можете использовать другие аннотации, области видимости и т. Д. Без необходимости развертывания собственного кода.И чем меньше кода на заказ, тем лучше IMO.Я оставлю последнее слово Фаулеру:

Выбор между локатором службы и внедрением зависимости менее важен, чем принцип отделения конфигурации службы от использования служб в приложении.

6 голосов
/ 09 июня 2011

Первый пример: x = Locator.getInstance (SomeInterface.class) выглядит как шаблон Service Locator, и http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx проверьте эту статью, в которой говорится, что Service Locator является анти-шаблоном и его следует избегать

И для второго использования все хорошо, мне нравится Constructor Injection, его плавная и точная реализация.Но я бы не хотел использовать атрибуты (annotanitons в Java?), Потому что в любое время я мог бы захотеть изменить используемый мной DI-контейнер, и я не хочу удалять атрибут из всех классов.

2 голосов
/ 02 ноября 2012

Шаблон поиска службы использует центральный реестр, известный как «указатель службы», который по запросу возвращает информацию, необходимую для выполнения определенной задачи.

Это худшие стороны шаблона проектирования сервисного локатора:

  • Вещи, помещенные в реестр, по сути являются черными ящиками с С уважением к остальной части системы. Это затрудняет обнаружение и оправиться от своих ошибок и может сделать систему в целом менее надежно.

  • Реестр должен быть уникальным, что может сделать его узким местом для
    одновременные заявки.

  • Реестр может быть серьезной уязвимостью безопасности, потому что он позволяет посторонним вводить код прямо в приложение.

  • Невозможно передать зависимости конструктором (как мы это делаем в шаблоне DI) и трудно провести юнит-тестирование

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

1 голос
/ 09 июня 2011

Нет ничего «неправильного» как такового в шаблоне поиска сервисов,

В этом конкретном случае одним из главных аргументов в пользу DI будет тестируемость.

Без сомнения, DI обеспечивает лучшее модульное тестирование. Статический метод getInstance в Locator затрудняет изолированное тестирование.

...