领域驱动设计的理解
要了解领域驱动开发,最好的方法是从一个实例入手,下面这个链接给出的例子就不错,简单易懂,但是每看一次可能对领域驱动就有一些更深入的理解。
http://kb.cnblogs.com/page/522125/
下面是我自己目前对领域驱动开发的一些理解。
传统的开发方式
传统的开发模型一般分为三层Controller/Handler, Service, Dao层。
- Controller/Handler: 负责承接Web前端或者其他系统(中间件)发送过来的请求,并将请求分发给Service层。
- Service:处理具体的逻辑,对于数据库操作,委托给Dao层。
- DAO: 负责数据库的访问。
其实在传统开发的初期我们也会按照业务领域对代码结构进行划分,比如每个页面都有自己对应的Controller、Service和Dao对象。
随着业务越来越复杂,Service层会出现以下问题:
- 业务逻辑越来越复杂,代码越来越多。
- 刚开始一个Service可能只包含对一个数据库表的增删改查的逻辑,后来可能会需要依赖其他的数据库表,这样就需要依赖其他的Dao对象或者Service对象。最终导致Service层出现复杂的交叉依赖。
为了解决上述问题,我们需要对Service层进行分拆,把一些公用的功能抽出来单独放到一个Service,原来按照页面进行划分的方式已经不够细了。这时我们可能需要按照业务领域进行拆分了。但是由于代码逻辑已经非常复杂,我们甚至不知道一个Service到底包含了哪些业务领域,哪些代码在不同的Service里面重复出现。问题的症结在于传统的Service没有一个<b>明确的业务边界</b>(也许刚开始设计的时候有)。
领域驱动开发模型
之前提到了传到开发方式没有明确的业务边界,导致业务复杂之后很难拆分。那么为什么不开始就设置好明确的边界呢?
传统开发方式将模型(贫血模型)与业务逻辑分离开了,随着业务复杂性的增加,原有的Service类最终会逃离模型的限制而变得没有边界。那么设置明确边界的最好方式就是把业务逻辑放到模型里面来。这其实就是面向对象设计,一个模型拥有自己的属性以及职责范围内的方法。传统的分层开发只不过是面向过程设计(虽然Java是面向对象的,但是大多数时候我们还是在用面向对象的语言进行面向过程的设计)。
领域驱动开发的优势
- 更易于不懂技术的人去理解系统的整体架构,这有就能够和业务方面的专家进行沟通。
- 将业务逻辑限制在模型里面,这样后续的开发人员就会有比较明确的感知,哪些逻辑适合放到哪个类里面。
- 当你需要某个服务的时候,你能很容易的找到提供服务的类,减少代码的重复。
一个大型系统的设计思路
比如我们需要为某个电商企业的各个部门设计一整套软件系统。
面向服务架构(SOA)
首先我们用SOA的思想划分子系统,比如一个企业的系统可以划分为:
人事,财务,后勤,核心业务(电商网站)
每个子系统向外暴露自己的服务。
分层架构与领域驱动设计
对于每个子系统,我们可以采用分层架构和领域驱动设计
Controller, Service, Model(领域模型), Dao
其中Service主要是把领域模型串联起来提供某个业务流程的服务。
注意事项
- 模型是有状态的,不是单例的。
- 模型不应该包含对自身的创建逻辑。
- 模型只能包含对自己属性的操作,比如用户模型,只能包含对某个用户的操作,而不应该包含整个用户集合的操作。