我正在构建的软件的中心原则是“工单”
在我看来,WorkOrder 将是一个“聚合根”,其中包含有关工作订单的基本信息,例如创建日期、型号/制造商、序列号、采购订单。
除了这些“价值”对象之外,还有子“实体”或“聚合”,例如:
- 序列
- 返工
- 方面
- 报价单
- 消耗品
如果没有相关的工单,上述任何一项都不能/不应该存在。在现有系统中,他们实际上偶尔会这样做,但这是因为缺乏事务或代码检查以确保完整性。它们是孤立的记录,并通过定期清理删除 - 这是我更多地了解 DDD 和 ORM 以加快我们的开发实践的众多原因之一。
注意:这可能是题外话,可能会在您的回复中被跳过
因为我们主要是使用extJS的基于web的界面,每个列表控件显示上面的每一个,我一直不愿意切换到ORM和DDD。每个列表都通过一个查询数据库的控制器:操作填充(即:当 JS 控件使用 GET 命令调用序列 REST URI 时填充序列列表)。此 GET 命令调用实例化序列对象的控制器并调用selectAllForWorkorderID方法
我对 ORM 的理解是我会使用存储库来查询这些项目。很好,但是如果这个序列对象(在 DDD 用语中)被认为是 WorkOrder 根的聚合 - 那么我必须首先找到工作订单并通过 WorkOrder 遍历序列。
在基于 AJAX Web 的上下文中,这对我来说很有趣 - 但在桌面环境甚至标准的基于 Web 的上下文中,这是可以接受的,因为每次在主列表中选择 WorkOrder 项目时,我只会查询一次 WorkOrder 对象。每个要填充的单独列表不是 6 或 8 次。
我现在可以看到,我们的系统实际上有几个聚合根对象,工单只是少数几个中更复杂的一个:
- 工作指示
- 保证
- 维修订单
是主根。保修取决于工作订单 ID,维修订单可以但并非总是如此。
忽略后者的根源 - 让我只关注 WorkOrder。
当我开始检查现有模型并尝试确定什么是业务逻辑和/或应用程序逻辑时,我有点困惑。“服务”与“聚合根”的区别。
在当前模型中考虑一种这样的方法:
createWorkOrderFromRpi。
RPI 是经批准的文件,可作为 WorkOrder 的模板——它们规定了“可以”执行的顺序和执行顺序、尺寸、耗材清单等。这完全是一个单独的系统,我认为最好将其描述为“模块” “在 DDD 命名法中。
该方法需要查询RPI系统,获取工单头明细、序列表、耗材等。
一旦有了这些数据,它就会调用相关的对象和方法:
- WorkOrder.Create(标题详细信息)
- Sequence.Create(Sequence Details) - 循环完成 (1:m)
- Consumable.Create(Consumable Details) - 循环完成 (1:m)
在遵循 DDD 时,我很想让 WorkOrder “聚合根”提供一个具有相同签名的方法,但我不愿意这样做。
我相信作为 WorkOrder 聚合的每个“实体”都符合描述,并且不应该暴露于“根”之外的任何东西,除非遍历根本身。在某些情况下,情况并非如此。On second thought, the interface only ever exposes consumables and sequences and such when a work order is selected which would imply a work order must be loaded anyway?!?
此方法必须执行一些基本的业务规则:
- 具有相同序列号的工作订单尚未在系统中有效(除非已归档),除非它在分包合同中,在这种情况下不要创建新工作,而是接收此工作订单的维修订单。
还有一些“规则”,但为了简洁起见,我将它们排除在外。
各个实体执行微业务验证,例如序列号等某些字段具有特定格式,部件号和采购订单号也是如此。
上面给出了我的主要问题或担忧,这种方法最好在“聚合根”或“服务”中实现吗?
更新 | 最后一个问题......如果聚合根是正确的概念......我需要访问序列,以便我可以更新我将在概念上访问的字段(忽略语法),例如:
WorkOrder.Sequences(0).moveToNext()
如果这个方法是在序列“实体”中实现的,那是有道理的。技术细节和业务逻辑的划分在哪里?例如,要将工作订单从一个序列移动到下一个序列,我们更新每个序列的三个时间戳:
date_entered date_started date_finished
设置最后一个时间戳后,下一个序列 date_entered 设置为与前一个序列 date_finished 相同的时间,系统现在知道这是活动序列。那是技术问题。
但是业务规则或约束是:
- 如果移入历史记录,请勿移动工单
- 返工时不要移动工单
- 如果在 subcon 中,请勿移动工单
这些是规则,我希望将它们分开和区分,以便我可以轻松地以规范文档的形式翻译成英文,我可以将管理呈现为动态文档和功能证明。我有点希望这就是 DDD 以干净的方式强制/促进的。这是独立于 DDD 处理的要求吗?这就是 CQS 的用武之地吗?将业务规则与与利益相关者零相关的技术问题分开?
亚历克斯