从 N 层转换为 DDD

Converting from N-Layer to DDD

我正在努力了解如何通过让我的域实体拥有它们的行为来重构我的站点以使其代码更清晰。

我希望我已经设法在这张图中描述了我的问题:

A 是我当前的 Web 应用程序项目设计,而 B 是我的目标设计。

我正在尝试将所有逻辑从我当前的 BL 插入到我的实体中,这样代码行如下:

var customer = new CustomerLogic().GetCustomer(id);

会变成:

var customer = new Customer(id);

或者,

var customer = Customer.Get(id);

看到多态的情况就更明显了。

问题是,在我当前的设计中 (A) 实体只是被使用,因此所有项目都引用它,未来的设计 (B) 实体必须有对较低层的引用。

但是由于我还希望我的 DAL 将我的实体传送回调用客户端,所以我得到了一个循环引用。

我当前的设计使我的代码比面向对象的代码更具过程性,我想改变它。

那么,如何在保持 DDD 的同时解决这个循环引用?

你通过inverting来自实体的依赖解决循环依赖(在DDD中是聚合,其中每个聚合包含一个聚合根和零个或多个嵌套实体).换句话说,领域层不应该依赖于其他层,比如持久层、应用层或表示层。

一个完整的用例是这样的:

customerId = request.get('customer_id')
customer  = repository.load(customerId)
customer.doSomethingImportant() //business logic that doesn't need anything from other layers
repository.save(customer)

如果不知何故,您的聚合需要来自外部的一些信息来完成其工作,那么您将该信息作为参数传递,如下所示:customer.doSomethingImportant(some, info, fromOutside).

您在这里应该注意的一个重要方面是聚合的 方法除了它自己的状态 之外不会改变任何其他东西。例如,它不发送电子邮件,不写入文件,甚至不写入数据库。然后,该变异状态由存储库获取并保存在数据库中。通过这种方式,您可以反转对 DAL/Database 的依赖。

在事件溯源中,这种变异状态采用领域事件的形式。在 flat/classic 架构中,存储库(通常是 ORM)计算差异并对数据库执行更改。