Должен ли уровень обслуживания сохранять какое-либо состояние? или он вводится только через конструктор / сеттер? - PullRequest
2 голосов
/ 12 января 2010

У меня есть OrderService, который я использую в своих контроллерах.

То, что я сделал, было просто унаследовано от пользовательского контроллера, где я добавил OrderService в качестве свойства. Я инициализирую OrderService в событии OnActionExecuting.

При инициализации OrderService я устанавливаю свойство Order.

Это связано с тем, что OrderService выполняет действия с ордером, поэтому имеет смысл установить его один раз, а не передавать ордер в каждый метод.

Соответствует ли этот дизайн передовой практике?

public class MyController : Controller
{
      public OrderService OrderService {get; set;}

      protected override void OnActionExecuting(...)
      {
          OrderService = new OrderService(getOrderIdFromCookie());

      }
}



   public class OrderService
   {
        private Order _order;

        public OrderService(int orderId)
        {
          _order = Dao.GetOrderById(orderId);
        }


        public void AddProduct(Product product)
        { 
            product.OrderId = _order.Id;   // assumes order is loaded
            ProductDao.Add(product);
        }

   }

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

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

Методы не должны предполагать, что объект Order имеет состояние.

Если это так, то мой дизайн не верен, верно?

Ответы [ 4 ]

2 голосов
/ 12 января 2010

Сервисный слой не должен быть Singleton.

Он также не должен включать состояние объекта.

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

public interface IOrderService
{
    public void AddProduct(Order order, Product product);
}

public class DaoOrderService : IOrderService 
{ 
    public Order GetOrder(orderId)
    {
        return Dao.GetOrderById(orderId);
    } 

    public void AddProduct(Order order, Product product) 
    {
        // The way this method works seems like it should be in a ProductService
        // rather than in the OrderService.
        product.OrderId = _order.Id;
        ProductDao.Add(product); 
    } 
}

И тогда у вашего контроллера будет что-то вроде:

public class MyController : Controller 
{    
    public IOrderService OrderService { get; private set; }

    public MyController(IOrderService orderService)
    {
        OrderService = orderService ?? new DaoOrderService();
    }

    public MyController()
        : this(null)
    { }

    protected override void OnActionExecuting(...) 
    {             
        Order myOrder = OrderService.GetOrder(orderId);

        // Some stuff here
        orderService.AddProduct(myOrder, selectedProduct);
    } 
} 
1 голос
/ 12 января 2010

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

Это означает, что вместо

    public void AddProduct(Product product)
    { 
        product.OrderId = _order.Id;   // assumes order is loaded
        ProductDao.Add(product);
    }

Вы просто делаете:

myOrder.Products.Add(product);
Service.Save(myOrder);
0 голосов
/ 12 января 2010

Вы правы, что ваш подход несколько необычен в описанных вами способах.

Современная мудрость предполагает, что «Сервисный уровень» или «Сервисный класс» не содержит состояния - он будет принимать все входные данные (включая порядок) в качестве параметров для своих функций API. Но (fwiw) ваш сервис кажется просто объектом .NET в памяти, а не WebService, EJB или другим сетевым сервисом. Вам вообще не обязательно называть это «обслуживанием».

Ваш объект может быть 'OrderProcessor' или, что еще лучше (возможно), вы можете просто объединить свой класс обслуживания с самим классом заказа.

Хотелось бы дать более полное описание вместе с убедительной рекомендацией, но трудно (для меня) быть очень самоуверенным, просто глядя на пару интерфейсов. Практики, на которые вы ссылаетесь, были созданы, чтобы обеспечить преимущества в определенных обстоятельствах. Если я не знаю, каковы ваши обстоятельства на самом деле, тогда утверждение, что вы знаете «правильный» ответ, по существу Программирование Cargo Cult .

0 голосов
/ 12 января 2010

Службу я обычно рассматриваю как группу методов, которые я вызываю в любое время, когда мне нравится. Насколько я понимаю, сервис всегда есть , и мне не нужно его создавать. Хотя могут быть случаи использования, которые могут быть реализованы с помощью чего-то вроде сервисных фабрик.

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

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

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