关于ABP——领域服务的思考

我在刚接触ABP的时候一直有一个疑问——有了应用服务,为什么还需要领域服务呢?

领域服务和应用服务对比

领域服务 应用服务
返回值 Entity DTO
被表现层调用 不可以(非强制) 可以

在ABP里面不是强制要使用领域服务的,但使用领域服务是个比较好的实践。

什么时候使用领域服务?

  1. 处理的是业务,而非场景(use-case)
  2. 要对Entity的状态修改加限制

举例

  • 栗子 电商的商品扣除库存
    假设我们写在应用层
    定义以下应用服务:

     public interface IStockApplication
     {
         ...
         bool Reduce(ProductDto product, int qty);
     }
     public interface IOrderApplication
     {
         ...
         void Submit(OrderDto order);
     } 
    

可能会造成的问题:

  1. 扣库存这个业务就会暴露给表现层,造成表现层可能出现直接调用的情况,这是应该避免的。
  2. 开发Submit方法的技术人员不知道IStockApplication.Reduce,而是直接操作Product实体

解决问题:
将Product实体的Stock属性设置为只读,定义领域服务

public class Product
{
    ...
    //库存
    public int Stock{get; protected set;}

    //保留库存
    public int RetainStock{get;set;}

    internal bool Reduce(int qty)
    {
        //检查库存
        if(RetainStock > Stock-qty)
            return false;
        Stock-=qty;
    }
}
 public interface IStockDoman
 {
     ...
     bool Reduce(ProductDto product, int qty);
 }
 public class StockDoman:IStockDoman
 {
    ...
     bool Reduce(Product product, int qty)
    {
        ...
        product.Reduce(qty);
        ...
        return true;
    }
 }
 public interface IOrderApplication
 {
     ...
     void Submit(OrderDto order);
 } 

这样就有效的避免了上述问题

posted @ 2017-01-13 17:16  莫笑少年痴狂  阅读(1096)  评论(0编辑  收藏  举报