带来过程化代码的是第二个选项。
可能更容易开发,但维护难度更大。
现实世界中,这是一个纯粹的管理任务。
“管理”任务应该是私有的,并通过公共、完全“领域化”的操作调用。最好还是编写易于理解的代码,从领域驱动。
我认为问题在于,对领域专家来说,“撤消上一个状态”没有多少意义。
更有可能是在谈论订单的制作、取消和填充。
以下内容可能更适合:
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;
}
}
我个人不喜欢使用"statuses"这个词,因为它们会自动共享到使用它们的所有内容上——我认为这是不必要的耦合。
所以我会采用类似这样的方式:
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));
}
class Canceled:Event<Order>{
void Canceled(Order order):base(order){}
}
}
class Customer{
private void BeHappy(){
Console.WriteLine("hooraay!");
}
class OnOrderCanceled:IEventHandler<Order.Canceled>{
void Handle(Order.Canceled e){
var order=e.Source;
order.Customer.BeHappy();
}
}
}
如果订单变得太庞大,您可能需要了解
有界上下文是什么(正如Eric Evans所说 - 如果他有机会再次写他的书,他会把有界上下文移到开头)。
简而言之 - 这是一种由领域驱动的分解形式。
这个想法相对简单 - 拥有来自不同视角/上下文的多个订单是可以的。
例如 - 来自购物上下文的订单,来自会计上下文的订单。
namespace Shopping{
class Order{
ShoppingCart Cart;
}
}
namespace Accounting{
class Order{
}
}
但通常域本身就避免了复杂性,如果您仔细聆听,它很容易被分解。例如,您可能会从专家那里听到OrderLifeCycle、OrderHistory、OrderDescription等术语,您可以利用它们作为分解的锚点。
注:请记住 - 我对您的领域一无所知。很可能我使用的这些动词对它来说完全陌生。