Вариант 2 наверняка приведет к процедурному коду.
Может быть проще в разработке, но гораздо сложнее в обслуживании.
Сейчас в реальном мире это чисто административная задача
Задачи «Администрирование» должны быть частными и вызываться через публичные, полностью «доменные» действия.Предпочтительно - все еще написан в простом для понимания коде, управляемом из домена.
На мой взгляд, проблема в том, что UndoLastStatus
не имеет особого смысла для эксперта в области.
Скорее всего, они говорят о создании,отмена и заполнение заказов.
Что-то в этом роде может подходить лучше:
class Order{
void CancelOrder(){
Status=Status.Canceled;
}
void FillOrder(){
if(Status==Status.Canceled)
throw Exception();
Status=Status.Filled;
}
static void Make(){
return new Order();
}
void Order(){
Status=Status.Pending;
}
}
Мне лично не нравится использование "статусов", они автоматически предоставляются всем, кто их использует - я считаю, что не нужномуфта .
Итак, у меня было бы что-то вроде этого:
class Order{
void CancelOrder(){
IsCanceled=true;
}
void FillOrder(){
if(IsCanceled) throw Exception();
IsFilled=true;
}
static Order Make(){
return new Order();
}
void Order(){
IsPending=true;
}
}
Для изменения связанных вещей при изменении состояния ордера лучше всего использовать так называемые события домена .
Мой код будет выглядеть следующим образом:
class Order{
void CancelOrder(){
IsCanceled=true;
Raise(new Canceled(this));
}
//usage of nested classes for events is my homemade convention
class Canceled:Event<Order>{
void Canceled(Order order):base(order){}
}
}
class Customer{
private void BeHappy(){
Console.WriteLine("hooraay!");
}
//nb: nested class can see privates of Customer
class OnOrderCanceled:IEventHandler<Order.Canceled>{
void Handle(Order.Canceled e){
//caveat: this approach needs order->customer association
var order=e.Source;
order.Customer.BeHappy();
}
}
}
Если Порядок слишком велик, вы можете проверить, что такое ограниченный контекст (как говорит Эрик Эванс - еслиу него была возможность написать свою книгу снова, он перенесет ограниченные контексты в самое начало).
Короче говоря - это форма декомпозиции, управляемая доменом.
Идея относительно проста - нормально иметь несколько ордеров с разных точек зрения, или контекстов.
Например, контекст «Заказ из магазина», контекст «Заказ из учета».
namespace Shopping{
class Order{
//association with shopping cart
//might be vital for shopping but completely irrelevant for accounting
ShoppingCart Cart;
}
}
namespace Accounting{
class Order{
//something specific only to accounting
}
}
Но обычно достаточно того, что домен сам по себе избегает сложности и легко разложим, если вы слушаете его достаточно внимательно.Например, вы можете услышать от экспертов такие термины, как OrderLifeCycle, OrderHistory, OrderDescription, которые вы можете использовать в качестве якорей для декомпозиции.
NB: Имейте в виду - у меня нулевое понимание вашего домена.
Вполне вероятно, что этиглаголы, которые я использую, совершенно странны для этого.