Как и где следует использовать методы объекта домена? - PullRequest
2 голосов
/ 14 июля 2011

Я работаю над моделью для приложения ASP.NET MVC с DI и ORM.

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

Допустим, у меня есть сущность Productи я объявляю ApplyDiscount метод на нем.Учитывая ID продукта, переданного из метода действия контроллера, я должен сначала запросить экземпляр продукта, используя этот ID, а затем вызвать метод ApplyDiscount.Но где должен выполняться код запроса?Является ли допустимой практикой объявление метода в моем сервисном слое, который принимает ID, запрашивает экземпляр Product, а затем вызывает ApplyDiscount для этого экземпляра?Или этот код должен идти куда-то еще?

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

Имеет ли код запроса на уровне сервиса полное поражение цели?

Ответы [ 3 ]

0 голосов
/ 14 июля 2011

Я действительно не вижу необходимости в слое сервиса здесь. Если логика влияет только на одну сущность, я бы поместил логику внутри самой сущности. (Очевидно, вы не должны доверять вводу пользователя, я просто показываю это как гипотетический код.)

public ViewResult ApplyDiscount(int productId, decimal percent)
{
    var product = Database.Get<Product>(productId);
    product.ApplyDiscount(percent);
    Database.Save(product);
    return View(product);
}

Продукт:

public void ApplyDiscount(decimal percent)
{
    this.Price = this.Price * (1 - discount);
}
0 голосов
/ 14 июля 2011

В настоящее время я использую статический метод Find для сущности, например:

public ActionResult ApplyDiscount(int id, decimal percent) {

   Product product = Product.Find(id);

   if (product == null)
      return HttpNotFound();

   var result = product.ApplyDiscount(percent);

   if (result.IsError)
      return ViewWithErrors(result);

   return RedirectToAction("DiscountApplied");
}

ApplyDiscount возвращает объект с ошибками проверки, которые могут быть сопоставлены с ошибками ModelState.

0 голосов
/ 14 июля 2011

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

Как правило, вы хотите, чтобы проверка выполнялась как можно раньше; то есть, если вам дали недопустимый идентификатор, вы должны убедиться, что вы перехватили это недопустимое условие, прежде чем начинать цепочку выполнения по всей вашей логике. Как правило, это означает выполнение запроса в контроллере и передачу результирующего объекта через уровень обслуживания; это изолирует функциональность запросов на высоком уровне в вашей цепочке выполнения и предотвращает необходимость реализации высокоуровневой логики исключения на уровне обслуживания (например, если весь набор идентификаторов признан недействительным, вы можете выполнить эту проверку за пределами вашего уровня обслуживания, таким образом изолируя эту связанную логику и удерживая вас от необходимости делать это внутри уровня обслуживания.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...