c# - 领域驱动设计 - 如何实现始终有效的状态
问题描述
我有一个带有 OrderItems 的域模型 Order。
订单必须
- 有一个经理
- 至少还有一个 orderItem。
我的订单构造函数如下
public Order(Manager manager, IList<OrderItem> orderItems)
{
if(manager == null) throw new ArgumentNullException(nameof(manager));
if(orderItems == null) throw new ArgumentNullException(nameof(orderItems));
if(orderItems.Count == 0)
throw new Exception("List must contain at least one item.");
foreach(var item in orderItems)
AddItem(item);
//assign values
this.manager = manager;
...
...
}
Manager manager;
IList<OrderItem> orderItems;
...
void AddItem(OrderItem orderItem)
{
if(orderItem == null) throw new ArgumentNullException(nameof(orderItem));
if(orderItems.Contains(orderItem))
throw new Exception("Order Item duplicate");
orderItems.Add(orderItem);
}
void CreateNewOrder(int managerId, List<int> itemIdList)
{
Manager manager = managerRepo.FindById(managerId);
List<OrderItem> itemList =new List<OrderItem>();
foreach(int itemId in itemIdList)
itemList.Add(itemRepo.FindById(itemId));
Order order = new Order(manager, itemList);
orderRepo.Add(order);
}
我认为它接近持久性模型,而不是域模型。
如果我像下面这样编码怎么办?
public Order(Manager manager)
{
if(manager == null) throw new ArgumentNullException(nameof(manager));
this.manager = manager;
...
...
}
public void AddItem(OrderItem orderItem)
{
if(orderItem == null) throw new ArgumentNullException(nameof(orderItem));
if(orderItems.Contains(orderItem))
throw new Exception("Order Item duplicate");
orderItems.Add(orderItem);
}
public void ReadyForPersistence()
{
if(orderItems.Count == 0)
throw new Exception("Not ready for persistence");
}
void CreateNewOrder(int managerId, List<int> itemIdList)
{
Manager manager = managerRepo.FindById(managerId);
Order order = new Order(manager);
//Here order has zero item, does this mean order is in invalid state?
foreach(int itemId in itemIdList)
order.AddItem(itemRepo.FindById(itemId));
order.ReadyForPersistence();
orderRepo.Add(order);
}
我误解了“始终有效的状态”吗?
我怎样才能正确实现“始终有效的状态模型”。
解决方案
首先,我想说持久性与您的要求无关。问题真的是:空订单在您尝试建模的领域中真的有效吗?
如果空订单是错误的或在您的域中没有任何意义,我会说立即继续并在代码中强制执行此不变量。不允许完成任何会使订单处于不一致状态的方法。应用程序级代码(在本例中为CreateNewOrder
方法)最后是否具有有效顺序并不重要。另一个实现者可能会犯错误而忘记在其中添加项目;在这种情况下,您的订单不会强制执行它需要的不变量。
作为旁注,如果空订单有意义,这实际上取决于您正在从事的行业。请与您的主题专家交谈,以检查空订单是否不仅仅是名称不同的东西。您可能会发现空订单是有效的,具有自己的规则和操作,但它们有另一个名称,并且它具有一组不同的不变量,如果这样做,它可以使事情变得更加简单:您可以作为模型的一部分的“订单草稿”将作为您订单的工厂有机地工作。
推荐阅读
- c# - 单元测试服务中如何模拟存储库方法
- azure - 使用 ManagedServiceIdentity 从逻辑应用程序到 Azure 函数时出现 301 永久重定向
- javascript - JavaScript 购物车无法正常运行
- c++ - 无法从派生类对象访问父类函数
- c# - 根据该键的属性确定字典是否包含键?
- java - 运算符 <= 不能应用于“E”、“E”、泛型类
- sql - PostgreSQL:使用单个查询更新表中的多行
- c# - 单个参数字符串被视为多个参数 c# QueryHelpers
- mysql - Django Rest API:查看定义删除查询集
- php - 按其值着色行背景