在域层和表示层之间共享的DDD中放置业务逻辑的位置?

时间:2013-02-26 13:56:08

标签: wpf mvvm domain-driven-design

我正在使用DDD模式开发应用程序。

我在域层中有Invoice类。

public class Invoice
{
    List<InvoiceLine> list = new List<InvoiceLine>();

    public DateTime Date { get; set; }

    public Customer Customer { get; set; }

    public decimal GrandTotal 
    { 
        get
        {
            // Simplified grand total. 
            // It's actually include tax and discount to calculate.

            decimal total = 0m;
            foreach(InvoiceLine line in Lines)
                total += line.LineTotal;

            return total;
        }
    }

    public IEnumerable<InvoiceLine> Lines
    {
        get { return list; } 
    }

    public void AddLine(InvoiceLine line)
    {
        lines.Add(line);
    }
}

我正在使用mvvm模式,所以我还有一个viewmodel来编辑发票。我的问题是我应该在哪里放置业务逻辑来计算GrandTotal,以便域和表示的业务逻辑相同?

我应该只是将代码从域复制到演示文稿(InvoiceInvoiceViewModel)吗?或者提供域名和演示文稿都可以使用的服务?

1 个答案:

答案 0 :(得分:1)

DDD中聚合的主要目标是保持一致性 - 在您的情况下,一致性意味着例如GrandTotal将始终具有正确的值。也就是说,没有规则说聚合类不能使用其他类来获得这种一致性。

例如,您可以提供一个类,其唯一责任是计算总计并在您的域中使用它并查看模型。我不会称之为服务,因为它与DDD概念无关。例如:

public interface IInvoiceLine
{
    decimal Amount {get;}
}

public interface ICalculateGrandTotal
{
    decimal Calculate(IEnumerable<IInvoiceLine> lines);
}

public class GrandTotalCalculator: ICalculateGrandTotal
{
    ...
}

现在,您可以在视图模型和域中使用此计算器,而无需重复代码。此外,由于接口,视图模型和域类之间没有直接耦合。 IInvoiceLine接口可以由视图模型和域实体单独实现。