Сервисный уровень весной - автоподключение всех сервисов

Я думал о некоторых своих услугах. Некоторые из них выглядят так:

@Service
public class UserService {

   @Autowired
   UserDao dao;

   @Autowired 
   OtherService1 serv1;
   @Autowired 
   OtherService2 serv2;
   @Autowired 
   OtherService3 serv3;
   ....



}

Я подумал... если эта концепция автосвязывания других сервисов в один сервис довольно распространена, почему бы не создать "мастер-сервис":

@Service
public class MasterService {


   @Autowired 
   OtherService1 serv1;
   @Autowired 
   OtherService2 serv2;
   @Autowired 
   OtherService3 serv3;
   ...
   @Autowired 
   LastService servN;


}

и автопроводка этого сервиса во все сервисы.

@Service
public class AnyService {

   @Autowired 
   MasterService masterSevice;
}

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

Возникает два вопроса:

1) Так как masterService содержит все сервисы, у нас есть цикл инъекций. мы можем решить это?

2) если ответ на вопрос 1 "да" - это "masterService" хорошая практика?


person Urbanleg    schedule 20.08.2013    source источник


Ответы (4)


1) Spring во многих случаях может обрабатывать циклы зависимостей, особенно если не используются инъекции конструктора.

2) Несмотря на это. Вы должны полностью избегать этого дизайна. Это нарушает многие принципы хорошей архитектуры:

  • Компоненты должны иметь доступ только к тому небольшому количеству других компонентов, которое необходимо. Закон Деметры
  • Разделение забот. Сервис не должен одновременно обрабатывать бизнес-логику и представление.
  • Уровни абстракции. Служба не должна обрабатывать как логическое представление данных, так и представление их постоянства.

Нарушение этих принципов может привести к таким плохим ситуациям, как:

  • Невозможность следовать путям кода (один запрос будет проходить через 12 служб в сложном для понимания порядке, основанном на многих уровнях условной логики).
  • Сложно понять, какие компоненты зависят друг от друга.
  • Сильно связанный код (изменение услуги низкого уровня приведет к изменению услуг высокого уровня).

Преимущества, которые вы получаете от такого дизайна, очень малы (вы просто избегаете нескольких @Autowired аннотаций) и не стоят риска.

person ARRG    schedule 20.08.2013

  1. Зачем иметь циклическую зависимость? Существует одна служба, которая содержит все остальные службы, и нет другой службы, которая ее содержит. Сказав это, циклическую зависимость можно легко решить, установив зависимость как свойство, а не как аргумент конструктора.

  2. Я так не думаю, это хороший шаблон для объявления иерархии (например, в конечных точках), но каковы в этом плюсы? Вы можете Autowire любой сервис, который вы хотите, и без него.

person Noam    schedule 20.08.2013

1) MasterService не обязательно содержит цикл. Если это так, то вы столкнетесь с проблемами, и гораздо проще вообще не создавать свои bean-компоненты в цикле.

2) Это может быть эффективным, если вы внедряете множество недолговечных компонентов, но у этого подхода есть недостаток: любой, кто вмешивается в экземпляр MasterService, может испортить сервисы для других компонентов. Вы можете скрыть это за геттерными методами, но объединение всего в одну кучу обычно не дает большой пользы.

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

person chrylis -cautiouslyoptimistic-    schedule 20.08.2013

Такого паттерна я еще не встречал (один сервис содержит другие сервисы). То, что я обычно видел и использовал, выглядит примерно так:

* КонкретныйКонтроллер1 --> КонкретныйСервис1 --> КонкретныйДао1

КонкретныйКонтроллер2 --> КонкретныйСервис2 --> КонкретныйДао2

Теперь, если SpecificService1 нужны некоторые функции, уже доступные в SpecificService2, только тогда он будет ссылаться на SpecificService2.

Итак, у меня есть несколько вопросов по шаблону, описанному выше:

  1. Как будет использоваться MasterService? то есть любой контроллер (или кто-либо), которому требуется какая-либо служба, сначала использовал бы MasterService для получения ссылки на фактическую службу, или MasterService будет действовать как делегат?
  2. В каком случае нужен такой дизайн и в чем его преимущества?
person Rahul    schedule 20.08.2013
comment
1. ссылка, (публичные интерфейсы) 2. преимущество в том, что все публичные сервисы доступны из любого сервиса и без автомонтирования множества сервисов в каждом сервисе. причем при работе с xml преимущество еще больше - person Urbanleg; 20.08.2013