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

Inheritance DDD(域驱动设计)我可以使用继承吗?,inheritance,domain-driven-design,composition,aggregateroot,Inheritance,Domain Driven Design,Composition,Aggregateroot,考虑以下示例: 我们有秩序,任何秩序都可以有不同的类型 订单有事务,每种类型的订单都可以分配n个事务 例如: OrderA必须有一个事务 OrderB必须有两个事务 OrderC可以有n个事务 当我们更新订单的值时,我们需要根据特定于算法的订单类型计算事务的值 我们如何为这种情况设计模型? 我们可以在aggregateRoot中使用继承还是应该使用组合?比如说 /// <summary> /// AggregateRoot /// </summary> pu

考虑以下示例:

  • 我们有秩序,任何秩序都可以有不同的类型
  • 订单有事务,每种类型的订单都可以分配n个事务
例如:

OrderA必须有一个事务

OrderB必须有两个事务

OrderC可以有n个事务

当我们更新订单的值时,我们需要根据特定于算法的订单类型计算事务的值

我们如何为这种情况设计模型? 我们可以在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);
        });
    }
}
//
///聚合器
/// 
公共抽象类秩序
{
受保护的ISet_交易;
公共可数事务
{
获取{return\u transactions;}
}
公共抽象OrderType OrderType{get;}
公共十进制?值{get;protected set;}
公共无效设置值(十进制?值)
{
价值=价值;
UpdateReatedTransaction();
}
受保护的抽象void updateReatedTransaction();
}
公共类OrderA:Order
{
公共秩序
{
_交易。添加(新交易(本));
}
公共覆盖OrderType OrderType
{
获取{return OrderType.OrderTypeA;}
}
受保护的覆盖无效UpdateReatedTransaction()
{
ForEach(_事务,tran=>{tran.SetValue(Value);});
}
}
公共类OrderB:订单
{
公共秩序b()
{
_事务。添加(新事务(此)
{
状态=状态。打开
});
_事务。添加(新事务(此)
{
状态=状态。关闭
});
}
公共覆盖OrderType OrderType
{
获取{return OrderType.OrderTypeB;}
}
受保护的覆盖无效UpdateReatedTransaction()
{
EnumerableExtensions.ForEach(_事务,事务=>
{
if(trans.Status==Status.Open)
传输设置值(值);
if(trans.Status==Status.Close)
传输设置值(-1*值);
});
}
}

DDD根中的继承是一个棘手的话题。我认为大多数人(我想我在实现领域驱动设计时也读过这篇文章)会选择在AR中不进行继承

要考虑的主要问题是行为。不同的订单类型在将来的任何时候都会有不同的公共接口吗?如果答案是肯定的,那么您必须按照每个订单拥有不同的AR(以及存储库)。我知道你没有问这个问题,但最好记住:)

举个例子,IMHO使用composition没有多大价值,因为新的AR只是围绕Order的一个非常薄的包装器,而这个包装器除了委托之外没有任何责任。如果保持代码干净,重构(创建封装订单的AR)应该相当容易


免责声明:过去5年我一直在使用DDD,但我仍然很难理解它。。。因此,请接受我的建议,但不要小题大做。

不要忘记,值对象可以有行为。也许您的订单类型可以是值对象,每个具体的VO可以实现特定于类型的算法。订单类型基本上会成为一种策略。那适合你的需要吗?