在使用域驱动设计构建的应用程序中,我遇到了一些问题。
我有以下几层:
那么,让我们假设我有以下类:
OrderEmailServiceOrderNotificationServiceOrderApplicationService显然,Order在域层,OrderApplicationService在应用层。EmailService是一种用于发送电子邮件的通用服务,并在基础设施层实现。OrderNotificationService是用于发送订单通知的特定实现。OrderNotificationService使用EmailService发送实际的电子邮件。
因此,我的第一个问题是:OrderNotificationService是作为域服务、应用程序服务还是基础设施服务实现的?
对于我的下一个问题,让我们假设以下对象:
EmployeeSalesforceService假设当员工被添加到系统中时,他们也应该被添加到Salesforce中。SalesforceService是一个使用Salesforce注册用户的服务。SalesforceService是作为域服务还是应用程序服务通过发送员工信息使用的通用基础设施服务来实现的呢?
谢谢你的建议。
发布于 2012-09-08 00:09:30
这听起来不像DDD
你的问题中并没有太多关于你的领域模型的内容。您提到了“员工被添加到系统和Salesforce中”,但除此之外,我对您的应用程序在业务上的意图没有真正的了解。我对“雇员”和“销售人员”的理解是基于对这些词的熟悉程度,而不是对它们在系统中的模型的解释。
我不太清楚“订单应用服务”在您的模型中应该代表什么。我得到了“订单”和“订单通知”。似乎是“客户”发出了“订单”,一些“订阅者”得到了“通知”,但很多这都是基于我对设计模式的先验知识。
--你应该能够描述业务领域模型,因为如果计算机不存在,它就能工作。如果你需要一个计算机术语来解释这个想法,那么它很可能是混合在模型之外的东西中。
显然,您需要将应用程序逻辑与域逻辑集成起来,但这不应导致混淆您的关注点。然而,有一些方法可以解决这个问题。
你怎么能修好它
IOrderNotificationService的void NotifyOrderReceived(Order order);接口。这样,您就可以在域层中获得所需的所有业务逻辑,而无需引入不必要的关注点,如“电子邮件”实现或数据库持久性。我猜想这一点,但您的OrderNotificationService和OrderApplicationService实际上是对同一事件的响应,但其中一个具有数据库依赖性,另一个具有SMTP依赖。两者都是基础设施方面的问题。在许多情况下,针对单个接口进行编码就足够了。但是,存在一个问题,您的域对象现在依赖于注入的服务或全局变量。此外,这可能表明这些实体对其依赖性了解得太多了。客户可能不需要知道订单是如何处理的,但只需要知道订单已经处理,他们就会收到订单。类似地,员工可能不会加入销售团队,因为他在成为员工之前不知道这件事。他只知道他刚找到一份工作。
这个问题有一个很好的解决办法。
- [How to create fully encapsulated Domain Models](http://www.udidahan.com/2008/02/29/how-to-create-fully-encapsulated-domain-models/)
- [Domain Events – Take 2](http://www.udidahan.com/2008/08/25/domain-events-take-2/)
- [Domain Events - Salvation](http://www.udidahan.com/2009/06/14/domain-events-salvation/)
现在,如果您是那种喜欢在完全理解代码之前复制和粘贴代码的开发人员,我建议您从第三个帖子开始。他们记录了Udi Dahan的思想和经验与模式的演变。最合理的代码示例出现在第三篇文章中。理想情况下,您应该按照顺序阅读这三种方法,这样您就可以遵循他的逻辑,并真正理解如何从他的方法中获益,以及为什么它准确地表示“领域驱动设计”。
作为“领域事件模式”的补充,埃里克·埃文斯(Evans)2009年回顾了他写了一本开创性的书以来对领域驱动设计( Domain )的了解,他指出,在他的书中,领域事件是一个明显被忽视的核心构建块。他的演讲摘要是可用的here,指向演示文稿的链接是可用的here。
其他一些可能帮助您成功应用此模式的资源包括Jimmy的文章“Strengthening your Domain: Domain Events和Martin Fowler's Domain Event article”。Bogard有链接到其他有用的DDD博客文章,从引用的链接。
总体而言,
如果您真的想尝试应用领域驱动的设计,那么通过真正了解您正在建模的内容以及实现什么目的,您将获得更大的成功。简单地使用您不熟悉的术语并将您的代码贴上标签是没有隐含价值的。DDD是非常有用的,但是如果你不花时间去理解你为什么要做出区别和设计决策,你最终会有很多不必要的抽象和一般的混乱。
发布于 2012-09-07 22:44:43
OrderNotificationService属于域层。如果您认为它是Order类的协作者,那么它应该靠近Order类。海事组织,我认为OrderNotificationService可以被称为OrderNotifier,它的职责是在订单状态发生变化时发布通知。它显然是一个接口,而不是一个具体的类。它可以由属于基础结构或应用层的OrderNotificatoinService实现。没有必要使OrderNotificationService成为一个接口。
这同样适用于SalesforceService。将其视为Employee类的协作者,它负责在创建员工时注册新员工信息。它属于域层。与前一种情况一样,您可以考虑将其重命名为EmployeeRegister或类似的名称,这些名称描述了它的角色,而不是它的实现。而是用SaleforceService实现它。
一个副作用是您的域对象(Order/Emplyee)间接地依赖于应用程序/基础结构层的类。如果域对象是由其他域对象实例化的,则在创建域对象时,您可能会发现很难注入第三方依赖项。这篇文章可能很有用。http://thinkinginobjects.com/2012/09/05/abstract-factory-in-domain-modelling/
https://stackoverflow.com/questions/12322736
复制相似问题