Consider the following example:
For example:
OrderA must have one transaction.
OrderB must have two transaction.
OrderC can have n-transaction.
When we update the value of the Order, we need calculate the value of the transaction according to the algorithm -specific order type.
How can we design a model for this case ? Can we use inheritance in aggregateRoot or maybe we should use composition ? For Example ?
/// <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);
});
}
}
Inheritance in DDD Aggragate Roots is a tricky topic. I think most people (and I think I also read this in Implementing Domain-Driven Design) would opt for not having inheritance in AR.
The main point to think about is behaviour. Will the different Order types have different public interface at any time in the future? If the answer is yes, then you have to go through the route of having different ARs per Order (and repositories too). I know you haven't asked this, but it's good to keep it in mind :).
Given your example, IMHO there's not much value of using composition, as the new AR would be just a very thin wrapper around Order, and that wrapper wouldn't have any resposibility other than delegate. If you keep the code clean, refactoring this (creating an AR that encapsulates the Order) should be quite easy.
Disclaimer: I've been using DDD for the last 5 years, and I still have a hard time getting my head around it... so take my advice with a pinch of salt.