DDD(域驱动设计)我可以使用继承吗?

时间:2015-02-22 11:09:51

标签: inheritance domain-driven-design composition aggregateroot

考虑以下示例:

  • 我们有订单,任何订单都可以是不同的类型。
  • 订单包含交易,每种订单都可以分配n-transaction。

例如:

OrderA必须有一个交易。

OrderB必须有两个交易。

OrderC可以进行n-transaction。

当我们更新Order的值时,我们需要根据算法特定的订单类型计算交易的价值。

我们如何为此案例设计模型? 我们可以在aggregateRoot中使用继承,还是应该使用组合?例如 ?

 /// <summary>
///     AggregateRoot
/// </summary>
public abstract class Order
{
    protected ISet<Transaction> _transactions;

    public IEnumerable<Transaction> Transactions
    {
        get { return _transactions; }
    }

    public abstract OrderType OrderType { get; }
    public decimal? Value { get; protected set; }

    public void SetValue(decimal? value)
    {
        Value = value;
        UpdateReleatedTransaction();
    }

    protected abstract void UpdateReleatedTransaction();
}

public class OrderA : Order
{
    public OrderA()
    {
        _transactions.Add(new Transaction(this));
    }

    public override OrderType OrderType
    {
        get { return OrderType.OrderTypeA; }
    }

    protected override void UpdateReleatedTransaction()
    {
        EnumerableExtensions.ForEach(_transactions, tran => { tran.SetValue(Value); });
    }
}

public class OrderB : Order
{
    public OrderB()
    {
        _transactions.Add(new Transaction(this)
        {
            Status = Status.Open
        });
        _transactions.Add(new Transaction(this)
        {
            Status = Status.Close
        });
    }

    public override OrderType OrderType
    {
        get { return OrderType.OrderTypeB; }
    }

    protected override void UpdateReleatedTransaction()
    {
        EnumerableExtensions.ForEach(_transactions, tran =>
        {
            if (tran.Status == Status.Open)
                tran.SetValue(Value);
            if (tran.Status == Status.Close)
                tran.SetValue(-1*Value);
        });
    }
}

1 个答案:

答案 0 :(得分:1)

DDD Aggragate Roots中的继承是一个棘手的话题。我认为大多数人(我认为我在实现域驱动设计中也读到这一点)会选择不在AR中继承。

要考虑的主要观点是行为。不同的订单类型将来是否会有任何不同的公共界面?如果答案是肯定的,那么你必须经历每个订单具有不同AR的路径(以及存储库)。我知道你没有问过这个,但记住这一点很好:)。

鉴于你的例子,恕我直言,使用组合没有多大价值,因为新的AR只是一个非常薄的Order包装器,而且这个包装器除了委托之外不会有任何可靠性。如果你保持代码干净,重构它(创建一个封装Order的AR)应该很容易。

免责声明:过去5年我一直使用 DDD,我仍然很难理解它...所以请听我的建议少许盐。