DDD - 子实体封装

时间:2014-02-20 20:26:26

标签: c# domain-driven-design aggregate encapsulation

给出以下示例聚合:

public class Order
{
    private readonly IList<OrderLine> _orderLines;
    public IEnumerable<OrderLine> Lines { get { return _orderLines; } }

    public Order()
    {
       _orderLines = new List<OrderLine>();
    }

    public void AddOrderLine(string sku, int qty)
    {
        _orderLines.Add(new OrderLine(sku, qty));
    }

    public void CancelOrderLine(string sku)
    {
         OrderLine line = _orderLines.FirstOrDefault(l => l.Sku == sku);
         if (line == null)
            return;

         line.Cancel();
    }
}

public class OrderLine
{
    public string Sku { get; private set; }
    public int Qty { get; private set; }

    public OrderLine(string sku, int qty)
    {
       Sku = sku;
       Qty = qty;
    }

    public void Cancel()
    {
        // do some cancellation stuff
    }
}

什么是阻止某人绕过聚合根并直接修改OrderLine?例如:

foreach(OrderLine line in currentOrder.Lines)
{
   line.Cancel();
}

是否有真正封装的聚合根?唯一的解决方案是创建一组并行的顺序线来代替暴露的对象吗?

感谢您的任何见解。

2 个答案:

答案 0 :(得分:1)

难道你不能开始将Cancel方法设为内部,因此只能在Order程序集中看到它吗? 当然,这个程序集中的其他类仍然可以访问取消方法。

也许另一种方法是将OrderLines集合公开为IOrderLine接口的集合,并以这种方式隐藏Cancel方法。

答案 1 :(得分:0)

为什么要暴露线条?公开一些快照(DTO),其中包含您需要的有关OrderLines的信息,而不是OrderLines本身。这是已知的解决方案。使用CQRS,您可能根本不需要公开它。