gpt4 book ai didi

domain-driven-design - 可配置规则驱动系统中的 DDD

转载 作者:行者123 更新时间:2023-12-04 04:31:19 28 4
gpt4 key购买 nike

请原谅这里的任何无知,我对 DDD 相当陌生,所以要温柔。

我正在开发一个大型配置驱动的数据管理系统。该系统是通过在外部语法中指定配置(如业务规则、流程和验证)来构建的。假设语法是基于 Groovy 的 DSL 和 Drools 的集合体。

我喜欢 DDD 提供的简单理念,特别是将基础设施问题与领域的核心概念分开。

但是,由于系统的可配置性,我很难应用 DDD 的一些概念。行为(流程)、验证和业务规则都是在系统外部定义的。因此,域中的实体本质上没有自己的行为。相反,他们对“验证器”或“规则引擎”或“工作流引擎”很敏感。

我将用一个例子来澄清。假设我的系统管理公司的员工。不用想太多,您会想象我的域中有一个员工实体和一个公司实体。

在 DDD 之后,我试图模拟一个员工升职的场景。您可能会在 Employee 上看到一个名为promote (Employee.promote) 的新方法。我们可以有一个业务规则,表明一个员工不能在同一年内晋升两次(是的,这都是编造的)。因此,我可以有类似的东西:

public void promote( EmployeeLevel newLevel ) {
if ( hasBeenPromotedThisYear( this ) {
throw new InvalidPromotionException

好吧,在我正在使用此业务规则的应用程序中,将被外部化为规则引擎。在 DDD 之后,我可以执行以下操作:
if( promotionRules.isEligibleForPromotion(this)

将我的规则外化。但是,该系统比这更通用。 “提升”操作本身通过外部配置定义为“进程”。因此,在编译时,我什至不知道我是否有可供该员工使用的“提升”操作。因此,从代码的角度来看,我的员工对象变得非常简单,将所有功能委托(delegate)给配置。它可能看起来像:
public class Employee {
public void execute( Process process )

或者,
public class EmployeeProcess {
public void process( Employee employee )

我的问题是:DDD 在这个应用程序中是否有意义?我是否应该只对非 DDD 意义上的流程、验证、业务规则(规则引擎)的协作进行建模?

我喜欢 Onion 架构,并且可以使用 UI -> App Services -> Core -> Infrastructure 来保持关注点的良好分离。但核心可能是上面提到的合作者,而不是真正的“领域概念”。

我的一部分认为,在这种情况下,“域概念”是验证器、处理器、业务规则,因为它们构成了我们在讨论系统时谈论的无处不在的语言。在这种情况下,我将拥有没有实际行为的实体(大部分情况下),以及实现系统行为的处理器、验证器、规则引擎方面的域概念。

添加更多信息。鉴于我上面的问题,我正在努力寻找一个看起来像这样的解决方案:

org.example.app

org.example.domain
- 员工
- 公司
- 员工级别

org.example.domain.shared
- 过程
- 商业规则
- 验证器

org.example.infrastructure

希望这个小片段能增加一点清晰度。

因此,Process、BusinessRule 和 Validator 概念将位于域内,但会根据系统所做的事情来支持域模型。

最佳答案

来自维基百科:

Domain-driven design (DDD) is an approach to developing software for complex needs by deeply connecting the implementation to an evolving model of the core business concepts.



我相信验证器、流程、规则不是你的核心业务概念。这些是相当常见的软件抽象。

我不是“按部就类”的 DDD 的忠实拥护者,但为了更加“领域驱动”,您的 DSL 和您的规则实际上应该围绕您的业务概念构建,以便更有意义地理解这一点。

在底层,您仍然可以使用验证器、流程、管理器、执行器等,但是如果您在其中使用业务概念而不是软件抽象,那么您的 DSL/规则将更具可读性。

更新 :由于您使用 Groovy 来定义 DSL,因此您可以使用 Groovy 的动态方法名称解析和构建器功能来创建可读的规则和类。您还可以利用“约定优于配置”原则来 Hook 某些逻辑。例如,在 Groovy 中,您可以尝试构建类似于:
if (employee is "promotable") {
start "promotion" for employee
}
is将是基域对象上的一个方法,它将检查是否存在假设 EmployeePromotableValidator 类,它本身也可以是利用 Groovy 的 DSL 表达能力的 Groovy 类。
class EmployeePromotableValidator extends Validator<Employee> {

boolean validate(Employee employee) {
employee.age > 25 && employee.workingYears > 2
}

}
start将是您的基本规则脚本中用于搜索 EmployeePromotionProcess 的方法类,这又可以是一个 Groovy 类。

这种情况下的规范模式非常简单,因为它基本上成为了语言的一部分:
if (employee is "promotable" && 
employee is "advanced" &&
employee.salary < 10000) {
start( "salary increase", "10%" ) for employee
}

一般来说,借助 Groovy/Scala 等(半)函数式语言的 DSL 可用于隐藏软件抽象并使您的业务逻辑在代码中更加突出。使用纯 Java,您最终会得到大量样板代码,这些代码最终会隐藏您的所有意图。

关于domain-driven-design - 可配置规则驱动系统中的 DDD,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12370910/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com