Почему не глыба все классы обслуживания в Метод фабрики (вместо того, чтобы ввести интерфейсы)?

Мы разрабатываем проект ASP.NET и инкапсулируем всю нашу бизнес-логику в обслуживании классы. Некоторые находятся в объектах области, но обычно это является довольно анемичным (из-за ORM, который мы используем, который не изменится). Для лучше включения поблочного тестирования мы определяем интерфейсы для каждого сервиса и используем D.I.. Например, вот несколько интерфейсов:

IEmployeeService
IDepartmentService
IOrderService
...

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

public EmployeeService : IEmployeeService
{
   private readonly IOrderService _orderSvc;
   private readonly IDepartmentService _deptSvc;
   private readonly IEmployeeRepository _empRep;

   public EmployeeService(IOrderService orderSvc
                        , IDepartmentService deptSvc
                        , IEmployeeRepository empRep)
   {
      _orderSvc = orderSvc;
      _deptSvc = deptSvc;
      _empRep = empRep;
   }
   //methods down here
}

Это действительно обычно не проблема, но интересно, почему бы не настроить класс фабрики, который мы раздаем вместо этого?

т.е.

public ServiceFactory
{
   virtual IEmployeeService GetEmployeeService();
   virtual IDepartmentService GetDepartmentService();
   virtual IOrderService GetOrderService();
}

Затем вместо вызова:

_orderSvc.CalcOrderTotal(orderId) 

мы звонили бы

_svcFactory.GetOrderService.CalcOrderTotal(orderid)

Каково крушение этого метода? Это является все еще тестируемым, это все еще позволяет нам использовать D.I. (и обработайте внешние зависимости как контексты базы данных и почтовые отправители через D.I. в и вне фабрики), и это устраняет большую установку D.I. и консолидирует зависимости больше.

Спасибо за Ваши мысли!

11
задан Andrew 25 March 2010 в 07:21
поделиться

3 ответа

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

Кстати, это не фабрика, если только вы не всегда создаете новый объект в методах Get [...] Service (), а делать это просто для передачи нескольких методов - плохо. Я бы просто назвал его ServiceWrapper и превратил бы их в свойства EmployeeService, DepartmentService и OrderService.

2
ответ дан 3 December 2019 в 10:25
поделиться

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

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

4
ответ дан 3 December 2019 в 10:25
поделиться

Такая фабрика по сути является локатором служб , и я считаю ее анти-шаблоном , потому что она скрывает ваши зависимости и упрощает нарушение единственной ответственности Принцип (SRP).

Одно из многих замечательных преимуществ, которые мы получаем от Constructor Injection , заключается в том, что он делает нарушения SRP настолько очевидными .

3
ответ дан 3 December 2019 в 10:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: