最近公司项目要求使用领域驱动设计,网上找了大部分资料发现都语焉不详,让人越看越迷糊。无奈只能拿到业内大作《实现领域驱动设计》([美]Vaughn Vernon)进行攻读。第一遍读我会粗略浏览,并提取一些关键性的东西记在这里。
目前读到书的第四章——架构,解决了我对DDD架构部分疑惑:
当我们去搜索相应的DDD项目时,往往遇到的项目结构是这样的:
上图为书中提供的经典架构。
根据书中的解释,这是一个松散分层架构(允许任意上方层与任意下方层发生耦合,或者说上方层可调用下方层,但下方层不允许调用上方层),其中每层的定义为:
-
用户接口层:用户接口层只用于处理用户显示和用户请求,它不应该包含领域或业务逻辑。如果用户界面使用了领域模型中的对象,那么此时的领域对象仅限于数据的渲染展现(我猜测在使用中将领域对象转化为DTO是个不错的选择)。
- 应用层:应用服务位于应用层中。应用服务(Application services)和领域服务(Domain Services)是不同的,因此领域逻辑也不应该出现在应用服务中(如何划分领域逻辑与应用逻辑?)。应用服务可以用于控制持久化事务和安全认证。应用服务本身并不处理业务逻辑,但它确却是领域模型的直接客户。
应用服务是很轻量的,它主要用于协调对领域对象的操作,比如聚合(此处稍微有些笼统)。因此,应用服务的通常用途是:接收来自用户界面的输入参数,再通过资源库(在基础设施层中,数据来源自数据库或者MQ等)获取到聚合实例,然后执行相应的命令操作。比如:
如果应用服务比上述功能复杂很多,这通常意味着领域逻辑已经渗透到应用服务中了,此时的领域模型将变成贫血模型(这里的解释是否意味着实体中将承担大量的业务逻辑)。因此,最佳的实践是将应用层做成很薄的一层。此外,应用服务还可以调用领域服务来完成和领域相关的任务操作,但此时操作应该是无状态的。
当领域模型用于发布领域事件(Domain Events)时,应用层可以将订阅方注册到任意数量的事件上,这样的好处是可以对事件进行存储和转发。同时,领域模型只需要关注自己的核心逻辑,领域事件发布器也可以保持轻量化,而不用依赖于消息机制的基础设施。
后两层待续。