我努力了解如何通过让我的域实体让他们的行为来重构我的网站以获得更清晰的代码。
我希望我能够在这个图表中描述我的问题:
A 是我目前的Web应用程序项目设计,而 B 是我的目标设计。
我试图将当前BL中的所有逻辑插入到我的实体中,以便代码行如下:
var customer = new CustomerLogic().GetCustomer(id);
将成为:
var customer = new Customer(id);
或者,
var customer = Customer.Get(id);
当我看到多态的情况时,它会更加明显。
问题在于,在我目前的设计中( A )实体只是被使用,因此所有项目都有参考,未来的设计( B )实体必须具有对较低层的引用。
但是因为我也希望我的DAL将我的实体交还给主叫客户,所以我得到一个循环引用。
我目前的设计使我的代码比面向对象更具程序性,我想改变它。
那么,如何在保持DDD的同时解决这个循环引用?
答案 0 :(得分:1)
您通过 inverting来自实体的依赖来解决循环依赖关系(在DDD中是聚合,其中每个聚合包含一个聚合根和零个或多个嵌套实体)。换句话说,Domain层不应该与其他层有任何依赖关系,如Persistence,Application或Presentation。
完整的用例如下:
customerId = request.get('customer_id')
customer = repository.load(customerId)
customer.doSomethingImportant() //business logic that doesn't need anything from other layers
repository.save(customer)
如果您的Aggregate需要来自 outside 的某些信息来完成其工作,那么您将该信息作为参数传递,如下所示:customer.doSomethingImportant(some, info, fromOutside)
。
您应该注意的重要方面是Aggregate的方法不会改变除了自己的状态之外的任何其他方法。例如,它不发送电子邮件,也不发送文件,甚至不发送到数据库。然后,存储库将使用该变异状态并将其保留在数据库中。通过这种方式,您可以将依赖项反转为DAL /数据库。
在事件采购中,此突变状态采用域事件的形式。在平面/经典架构中,存储库(通常是ORM)计算差异并对数据库执行更改。