写点什么

领域驱动设计 101 - 模块

用户头像
luojiahu
关注
发布于: 2 小时前
领域驱动设计101 - 模块

模块

在领域驱动设计中,模块(Module)对应的是 Java 语言中的包(Package),在其他语言中可能是其他的形式。

常见的 Java 包划分

受一些框架的影响,常见的 Java 工程,其包划分通常如下所示。


src/main/java  ├─controller    ├─entity    ├─manager  ├─repository    ├─service    └─util
复制代码


这种包划分方法从分层的角度出发,将类按照所属层次的进行分类。虽然从分层的角度看,这种划分方法非常清晰,但其问题在于:


  • 不能体现出领域内聚的语义,领域内与领域外没有明显的代码模块划分。

  • 很容易将业务规则散落在各层,写出类似事务脚本型的代码

  • 将所有的业务处理类都放在同一个包下面,随着时间的推移单个包可能变得很大,要找到某个业务对应的类如果不借助工具可能非常困难。

  • 同一个业务的处理流程被散落在各层当中,需要得到一个完整业务流程认识需要穿越各个不同的包获取。


DDD 倡导从领域的角度出发进行模块的划分。

按照领域进行包划分

按照领域进行包的划分要求首先从业务领域出发,在顶层按照领域进行包的划分,在领域包的内部再按照类的职责进行划分。这样划分的好处在于:


  • 在同一个领域包内部实现高内聚性,相关的业务规则不会超出这个包的范围。

  • 更加符合领域语言,直接将领域语言作为包的名字能够建立起非常清晰的设计与实现映射关系。

  • 模块/包即是领域中的关键要素(一等公民),体现了对应的领域知识 - 领域的划分。


一个按照领域出发的包划分例子如下:


src/main/java  ├─application  ├─domain  │  ├─article  │  │  ├─model  │  │  ├─repository  │  │  ├─service  │  │  └─vo  │  ├─author  │  │  ├─model  │  │  ├─repository  │  │  ├─service  │  │  └─vo  │  └─comment  ├─infrastructure  └─view
复制代码


首先,在领域之上是领域驱动设计对应的分层划分: view, application, domain, infrastructure,更进一步地可能有其他 facade 等其他层。另外,如果应用规模较大,可以将这一层作为开发工程模块的划分。


在 domain 层内(其他层也一样,未给出),首先按照领域 article 和 author 进行包的划分,在各自包的内部都有 model(实体), repository(接口定义), service(领域实现),vo(值对象)等子包。这样在领域包内部,所有的自包及其内部的类内聚地表达了一个完整的业务模型。从代码可维护性以及本身的表达性上看都更具有优势。

发布于: 2 小时前阅读数: 2
用户头像

luojiahu

关注

喜欢思考组织、过程、产品的后端开发 2017.01.08 加入

还未添加个人简介

评论

发布
暂无评论
领域驱动设计101 - 模块