我最近开始了一个使用现有数据库(Oracle)和 MVC 4 的项目。已经发生了很多编码......但代码中没有“策略”......只有 DB -> ORM -> 控制器。因此,我正在尝试为开发添加一些闪光,并练习一些 DDD 开发技术。
我已经定义了几个聚合根,每个都有一个存储库,用于处理保存和删除(及其子)等。这些聚合根中的一个引用了另一个聚合根,它通过它处理它的“子对象”它。
例子:
A Client has one or more purchase orders which has Line Items,
if a client wants to add a line item to the purchase order,
it has to go through the purchase order.
很好.. 客户 Aggregate Root,采购订单 Aggregate Root。
现在,一些服务也出现了,比如修改采购订单状态的服务,它消除了采购订单AR的负担,而且它很好、干净、有目的(它可以被其他“东西”用来更新采购订单的状态),(也许这应该是采购订单 AR 的一部分?一个小细节..)
存储库目前正在做他们的工作,即从数据库中持久化数据并用数据“填充” AR。当AR “保存”它时,存储库会保存任何需要保存的内容。客户AR使用采购订单存储库,因此客户可以加载它可能包含的任何采购订单。希望我走在正确的轨道上。
现在,进入MVC。所以我也有一些 ViewModel,它们基本上是关于需要向用户输出的内容的显示定义。Automapper 已经证明 frickin AWESOME,所以我可以“自动映射”到视图模型。不需要大脑,完美..
现在,真正让我失望的实施细节..
控制器目前正在通过一个客户端工厂工作,它返回一个客户端AR,然后它可以执行采购订单列表控制器需要做的任何事情,即管理相关的采购订单(作为一个整体,而不是采购订单的详细信息或本例中的数据)。
所以现在我想确保这是正确的..因为我看到的很多例子都有控制器与存储库而不是工厂一起工作,但我也看到工厂被推荐用于创建AR ..这让我相信在示例中,控制器正在处理聚合根,但是需要“消费者”的这种方式必须查询AR才能获取AR:
像:
Get the Client Aggregate where the ClientID is 15
或者更好:
get the Client Aggregate, where the ClientID is 15
and where active purchase orders > 0 ...or something..
这可能看起来像:
ClientAR = ClientRepository.GetClientByIDAndHasActivePurchaseOrders(15);
resultsImLookingFor = ClientAR.PurchaseOrders(); //or something
我觉得在这种情况下,存储库会根据我的需要“填充”ClientAR,所以现在我有了这个 ClientAR 东西,它根据它的使用情况而有所不同,它对我来说很臭……
使用工厂“感觉更好”,因为我只是从工厂创建一个 ClientAR 然后使用它,它不会根据情况而改变.. 它就是这样..
ClientAR = ClientFactory.CreateClient(15) // returns a ClientAR
resultsImLookingFor = ClientAR.GetPurchaseOrdersByStatus(statusID);
或者也许我完全想念它,我应该这样做::
ClientAR = ClientRepository.GetClientByID(15, PurchaseOrderSpec)
我错过了事物的规范方面吗?(在这一点上,我还没有足够的能力真正开始使用规范(只是还),因为我需要让这些东西正常工作)
我尽量不陷入实施的细节,因为我的老板当然不会对我是怎么做的..到目前为止,至少在考虑 DDD 的情况下实施事情(希望我得到它)已经证明非常好的可测试性和责任的逻辑“边界”,这是由这种“模式”或“思维方式”产生的,我想我应该说..
那么,我是否正确地接近这个?如果它是有争议的,我可以接受。如果它只是简单的错误,那么指导肯定是值得赞赏的,如果我离得很远,如果背后有充分的理由,建设性的批评不会伤害我的感情。
提前致谢。