Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Architecture 从N层到DDD的转换_Architecture_Domain Driven Design_N Layer - Fatal编程技术网

Architecture 从N层到DDD的转换

Architecture 从N层到DDD的转换,architecture,domain-driven-design,n-layer,Architecture,Domain Driven Design,N Layer,我正在努力理解如何通过让我的域实体拥有它们的行为来重构我的站点,使代码更干净 我希望我已经设法在这个图表中描述了我的问题: A是我目前设计的Web应用程序项目,而B是我的目标设计 我试图将当前BL中的所有逻辑插入到实体中,这样代码行如下: var customer=new CustomerLogic().GetCustomer(id) 将变成: var客户=新客户(id) 或者, var customer=customer.Get(id) 当我看到多态情况时,这一点就更加明显了 问题是,在我当

我正在努力理解如何通过让我的域实体拥有它们的行为来重构我的站点,使代码更干净

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

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

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

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

将变成:

var客户=新客户(id)

或者,

var customer=customer.Get(id)

当我看到多态情况时,这一点就更加明显了

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

但是,由于我还希望我的DAL将我的实体传递回调用客户机,因此我得到了一个循环引用

我目前的设计使我的代码比面向对象的更程序化,我想改变这一点


那么,如何在维护DDD的同时解决这个循环引用呢?

您可以通过实体的依赖关系来解决循环依赖关系(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/数据库


在事件源中,这种变异状态采用域事件的形式。在平面/经典体系结构中,存储库(通常是ORM)计算差异并对数据库执行更改。

您能否澄清您的用例应该位于哪一层?我猜需要有一个层,根据您的用例,它引用了存储库层和实体。所以它看起来像一个业务逻辑层。我说得对吗?你能叫那层别的吗?谢谢@Yaniver我的用例遍历表示(它知道
请求
)和应用程序。业务层将包含
doSomethingImportant
方法的主体(您在这里看不到)。从我对DDD书籍的阅读来看,域层依赖于基础架构层(其上有UI和应用程序层,也依赖于基础架构层)。此外,每个存储库都属于域层。依赖倒置是任何体系结构都可以做的事情,但在DDD分层体系结构中不需要它。@Rogério那本书很棒,但不是因为分层体系结构;该体系结构只是一个示例(在我看来是一个糟糕的示例),是一个实现细节,我们不应该认为分层体系结构===DDD。另一方面:我从未使用过它。在DDD中,域模型中的软件组件(例如,域服务或存储库)确实依赖于(即,具有编译时依赖性)来自“基础结构”(这是应用程序代码库的另一部分,无论您是否称之为“层”)的软件组件。这在实际项目中非常常见(例如,域服务类可能使用电子邮件发送类、数据库访问类或日期实用程序类,所有这些都是基础结构组件)。