nop*_*lay 9 domain-driven-design rules
请原谅任何无知,我对DDD相当新,所以要温柔.
我正在研究一个大型配置驱动的数据管理系统.通过在外部语法中指定配置(如业务规则,进程和验证)来构建系统.我们只是说语法是基于Groovy的DSL和Drools的集合体.
我喜欢DDD提供的简单性概念,特别是将基础架构问题与域的核心概念分离开来.
但是,由于系统的可配置性,我正在努力应用DDD的一些概念.行为(流程),验证和业务规则都是在系统外部定义的.因此,域中的实体本质上没有自己的行为.相反,它们对"验证器"或"规则引擎"或"工作流引擎"很敏感.
我将以一个例子来澄清.假设我的系统管理公司的员工.没有太多想法,您会想象我的域中有员工实体和公司实体.
在DDD之后,我试图模拟一个员工晋升的场景.您可能会在Employee上看到一个名为promote(Employee.promote)的新方法.我们可以有一个业务规则,表明员工在同一年内不能被提升两次(是的,这一切都已完成).因此我可以这样:
public void promote( EmployeeLevel newLevel ) {
if ( hasBeenPromotedThisYear( this ) {
throw new InvalidPromotionException
Run Code Online (Sandbox Code Playgroud)
好吧,在我正在使用此业务规则的应用程序中,将外部化为规则引擎.在DDD之后,我可以做类似的事情:
if( promotionRules.isEligibleForPromotion(this)
Run Code Online (Sandbox Code Playgroud)
外化我的规则.但是,该系统比这更通用."促销"操作本身通过外部配置定义为"过程".因此,在编译时,我甚至不知道我是否为该员工提供了"推广"操作.因此,从代码角度来看,我的员工对象变得非常简单,将所有功能委派给配置.它可能看起来像:
public class Employee {
public void execute( Process process )
Run Code Online (Sandbox Code Playgroud)
或者
public class EmployeeProcess {
public void process( Employee employee )
Run Code Online (Sandbox Code Playgroud)
我的问题是:DDD在这个应用程序中是否有意义?我是否应该在非DDD意义上模拟流程,验证,业务规则(规则引擎)的协作?
我喜欢洋葱架构,可以使用UI - >应用程序服务 - >核心 - >基础架构来保持关注点的良好分离.但核心可能是上面提到的合作者,而不是真正的"领域概念".
我的一部分认为,在这种情况下,"域概念"是验证器,处理器,业务规则,因为它们构成了我们在讨论系统时所讨论的无处不在的语言.在这种情况下,我会让实体没有真正的行为(大部分),以及处理器,验证器,规则引擎方面的域概念,它们实现了系统中的行为.
添加更多信息.鉴于我上面的问题,我正在努力寻找一个看起来像这样的解决方案:
org.example.app
org.example.domain - Employee - Company - EmployeeLevel
org.example.domain.shared - 进程 - BusinessRule - Validator
org.example.infrastructure
希望这个小片段增加一点清晰度.
因此,Process,BusinessRule和Validator概念将位于域内,但会根据系统所做的事情支持域模型.
来自维基百科:
领域驱动设计 (DDD) 是一种通过将实现与核心业务概念的不断发展的模型深度连接来开发满足复杂需求的软件的方法。
我相信验证器、流程、规则不是你的核心业务概念。这些是相当常见的软件抽象。
我不太喜欢“按书本”的 DDD,但为了更加“领域驱动”,您的 DSL 和规则实际上应该围绕您的业务概念构建,以使其更有意义。
在幕后,您仍然可以使用验证器、流程、管理器、执行器等,但如果您在其中使用业务概念而不是软件抽象,您的 DSL/规则将更具可读性。
更新:由于您使用 Groovy 来定义 DSL,因此您可以使用 Groovy 的动态方法名称解析和构建器功能来创建可读的规则和类。您还可以利用“约定优于配置”的原则来挂钩某些逻辑。例如,在 Groovy 中,您可以尝试构建类似于以下内容的内容:
if (employee is "promotable") {
start "promotion" for employee
}
Run Code Online (Sandbox Code Playgroud)
is将是基域对象上的一个方法,它将检查 EmployeePromotableValidator 类是否存在,该类本身也可以是利用 Groovy 的 DSL 表达能力的 Groovy 类。
class EmployeePromotableValidator extends Validator<Employee> {
boolean validate(Employee employee) {
employee.age > 25 && employee.workingYears > 2
}
}
Run Code Online (Sandbox Code Playgroud)
start将是基本规则脚本上的一个方法,它将搜索EmployeePromotionProcess类,该类也可以是 Groovy 类。
在这种情况下,规范模式非常简单,因为它基本上成为语言的一部分:
if (employee is "promotable" &&
employee is "advanced" &&
employee.salary < 10000) {
start( "salary increase", "10%" ) for employee
}
Run Code Online (Sandbox Code Playgroud)
一般来说,在(半)函数式语言(如 Groovy/Scala)的帮助下,DSL 可用于隐藏软件抽象并使您的业务逻辑在代码中更加突出。使用纯 Java,您最终会得到大量样板代码,这些代码最终会隐藏您的所有意图。
| 归档时间: |
|
| 查看次数: |
1569 次 |
| 最近记录: |