考虑以下示例:
例如:
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);
});
}
}
答案 0 :(得分:1)
DDD Aggragate Roots中的继承是一个棘手的话题。我认为大多数人(我认为我在实现域驱动设计中也读到这一点)会选择不在AR中继承。
要考虑的主要观点是行为。不同的订单类型将来是否会有任何不同的公共界面?如果答案是肯定的,那么你必须经历每个订单具有不同AR的路径(以及存储库)。我知道你没有问过这个,但记住这一点很好:)。
鉴于你的例子,恕我直言,使用组合没有多大价值,因为新的AR只是一个非常薄的Order包装器,而且这个包装器除了委托之外不会有任何可靠性。如果你保持代码干净,重构它(创建一个封装Order的AR)应该很容易。
免责声明:过去5年我一直使用 DDD,我仍然很难理解它...所以请听我的建议少许盐。