什么是领域驱动设计DDD

“领域驱动设计(Domain Driven Design)”是Eric Evans在他的经典著作《领域驱动设计——软件核心复杂性应对之道》中首次提出来的概念。这本书于2003年8月30日出版,至今刚好整整十年了。在国内的几个论坛和社区(例如JDON,JavaEye,OSChina等)那里都曾经掀起过讨论的热潮。但时至今日,关于什么是DDD,仍然是众说纷纭,莫衷一是。博主从该书出版之时就开始关注DDD设计思想,并根据自己的领悟写出了一个DDD类库DDDLib(https://github.com/dayatang/dddlib),最近又与同事一起推出以DDDLib为核心的开源的JavaEE项目开发平台Koala(https://git.oschina.net/openkoala/)。因此,对于什么是DDD,博主试图根据自己的理解提出自己的看法。

如果要用一两句话描述DDD,那就是:

“领域驱动设计,就是以业务领域中的概念和机制为蓝本,用面向对象的方法设计软件系统的领域层。系统中的其余各层都以领域层为中心依次构建。”

下面分别解释。

1、以业务领域中的概念和机制为蓝本。

作为企业应用软件开发人员,最大的挑战,同时也是最大的乐趣的就是:我们是为别人的业务领域编写软件。为了能够为业务领域(问题域)编写正确的、适用的软件,我们必须深入理解现实业务领域的关键概念、业务规则和运行机制。做不到这一点,我们的软件必然是错漏百出的。我们通过学习、研究和探索业务领域,然后用一个概念模型来表达我们对业务领域的理解,这个过程叫做“领域建模”,形成的模型叫做“领域模型”,领域模型记录了业务领域中的关键实体、实体之间的关联、以及业务实体之间如何相互协作以实现业务功能。在企业应用开发的所有活动中,领域建模是最为关键的活动,在很大程度上决定了软件的成败。

好。现在我们对业务领域(问题域)有了深入的理解之后,如何来设计和实现软件(解决方案域)?当然答案是:参照领域模型来实现。领域模型中的概念和机制是业务领域中一代代业务专家和从业者智慧的结晶,想我们自己能够有多高深的道行,能够另起炉灶打造一套不同的概念和机制?所以模仿问题领域的模型来构造我们的软件解决方案,是最正确、最可行、最省力、最可验证的路径。

以银行借记卡为例,问题域中有“账户”这个概念,解决方案中就设计“账户”这个类对应。问题域中的账户能够转账给另一个账户,软件中的账户类就通过在账户类中定义transferFundTo()方法对应这个行为。问题域中的转账不允许超过账户余额,软件账户类中的transferFundTo()方法也必须保证这一点。

2、用面向对象的方法设计软件系统的领域层。

这一点是DDD和CRUD(以数据库为中心的增删改查)外观上最明显的差别所在。在CRUD范式中,领域类的实例不是一个对象,而是一种数据结构,它对应于数据库表中的一行记录,而不是对应于业务领域中的一个实体。它承载了其他软件类需要使用的数据,而本身没有定义任何行为。Martin Fowler等人将这些所谓领域对象称之为“贫血”对象,其实更准确的称呼是“伪对象”——披上对象外衣的数据结构。

在DDD范式中,领域对象是真正的对象,同时具有状态(数据)和行为(方法)。它对应于业务领域中一个实体,而不一定对应于数据库表中的一行记录(可能一个实体的数据分散保存到几个表中,也可能根本就不保存到数据库,而是保存到NoSQL、XML或其他文件中)。领域对象通过类中定义的方法封装和实现了业务领域逻辑,一个软件系统中所有领域对象的总和就包含了所有的业务逻辑、业务知识和业务规则。

因为采用面向对象的方法设计领域层,领域对象可以充分利用OO的继承、封装和多态等概念表述业务逻辑,利用策略、状态、门面等设计模式灵活处理业务变化,下面其他的博文会充分论述这一点。

3、以领域层为中心构建软件系统。

在企业应用四层架构(基础设施层、领域层、应用层和表示层)中,领域层定义领域概念,封装业务逻辑,是整个系统的中心。它直接映射到问题域(业务领域),包含而且仅包含领域知识。它不依赖于其他任何一层,其他各层都直接或间接依赖于它。所以,应该首先设计和实现领域层,随后才设计和实现其他各层。

领域层在实现业务逻辑的过程中可能需要用到某些技术机制来提供帮助,例如持久化、消息传送等等,基础设施层为领域层的需求提供技术实现方案。

通过领域层领域对象的不同排列组合,可以实现某些专门的应用,这些专门的应用就是由应用层的对象来使用领域层的领域对象来实现的。领域层的对象是领域通用的,应用层的对象是应用特定的。
表示层将领域对象暴露给人类用户或其他计算机系统,或者从人类用户或其他计算机系统接收命令,通过应用层最终更改领域对象的状态。

与CRUD模式相比,CRUD是以数据库关系模型为中心的,软件围绕着数据的存储、呈现和转换来进行构建;而DDD是以对象模型(领域模型)为中心的,软件围绕着领域对象的关联和协作来进行构建,这是两者最大的区别。

用同一套语言来描述问题域(业务)和解决方案域(计算机软件),消除业务和软件之间的界限,业务即软件,软件即业务,这就是领域驱动设计。

你可能感兴趣的:(crud,DDD,领域驱动设计)