背景
领域驱动设计(DDD)就是将业务领域概念对应到软件构件。关于这个主题的大多数作品和文章基于Eric Evans的书《领域驱动设计》——它主要从概念和设计的角度讲解了领域建模和设计方向。这些作品讨论了DDD的主要元素,例如实体,值对象,和服务等等,或者谈论一些概念,像统一语言,边界上下文和防腐层。
这篇文章的目的是从如何使用领域模型并且真正能实现它的角度谈论领域建模与设计。我们将看一下指南,最佳实践,以及技术领导和架构师能够在实现时使用到的框架和工具。领域驱动设计与开发也会被一些架构,设计和实现方面影响,例如:
业务逻辑
持久化
缓存
事物管理
安全
代码生成
测试驱动
重构
这篇文章讨论这些不同的因素如何在整个生命周期中影响项目实现,以及架构师应该寻找什么来用于完成一个成功的DDD实现。我将从一个典型的领域模型应该有的特征列表开始,以及什么时候在一个企业中使用领域模型(相对于一点也不使用领域模型或者使用一个贫血模型)。
文章包含一个简单的贷款处理应用来描述这里讨论的能够在真实的领域驱动开发的项目中使用的设计方案和开发最佳实践。这个简单的应用在使用一些框架,像Spring,Dozer,Spring Security, JAXB,Arid POJOs和Spring Dynamic Modules实现贷款处理的领域魔偶性。实例代码是JAVA,但是无论什么语言背景,大多数开发人员也是相当容易理解的。
介绍
一个领域模型提供了多个好处。下面是其中的一些:
它帮助团队在公司业务方和IT方建立了一个基本的模型,团队可以使用它来讨论业务需求,数据实体和处理模型。
模型是模块化的,可扩展以及容易维护的,因为设计本身反应了业务模型。
它改善了业务领域对象的可重用性和可测试性。
从相反的方面,我们看看当IT团队在开发中到大型企业软件应用时不使用领域模型的方法会发生什么。
在领域模型和开发上不投入精力导致一个包含“满满的服务层”和“贫血模型层”的应用架构——facade类(常常是一个无状态的会话Bean)开始堆积越来越多的业务逻辑,并且领域对象变成仅仅有getter和setter方法的数据载体。这种方式也导致领域特定业务逻辑和规则被分散(或者在多个场景中重复)在多个不同的facade类中。
在大多数场景下,贫血领域模型不是很划算。它们不能给公司带来比其它公司有竞争力的优势,因为在这种架构中实现领域业务规则的改变将花费很长时间开发和部署到产品环境。
在我们看一个DDD实现项目的架构和设计考虑点前,让我们看看一个富领域模型的特征。
领域模型应该关注一个特定的业务可操作领域。它应该和业务模型,策略和业务流程一致。
它应该和业务中的其它领域以及架构中的其它层隔离。
它应该可重用从而避免相同核心业务领域元素的任何重复模型和实现。
一个模型应该与应用中的其它层松散耦合,意味着在领域层的任何一边没有依赖。
它应该是一个抽象和独立的层使更加易于维护,测试和版本。领域类应该是在容器之外可单元测试的。
它应该是使用POJO变成模型来设计的,没有任何技术或者框架的依赖。
它应该是与持久化具体实现独立。
它应该在任何基础架构上有最少的依赖,因为它将离开这些框架仍可以使用。我们不能在任何额外的框架上有任何强的依赖。
为了在软件开发精力方面达到更好的投资收益,业务组和IT的高级管理部门必须允许在业务领域建模和实现上投入精力(时间,金钱和资源)。让我们看看实现一个领域模型的其它必要因素:
团队应该可以正常访问业务领域主题专家
IT团队(建模人员,架构师和开发人员)应该掌握好的建模和设计技能。
分析人员应该有好的业务过程建模技术。
架构师和开发人员应该有很强的面相对象谁及和开发经验。
企业架构中领域驱动设计的角色
领域建模和DDD在企业架构中有着至关重要的角色。因为企业架构的一个目标就是使IT与业务组保持一致,领域模型——正是业务实体的体现,就成为企业架构的一个核心部分。这是为什么大多数企业架构组件(业务或者基础)应该围绕着领域模型来设计和实现。
领域驱动设计与SOA
面向服务架构在过去的几年里越来越强进,帮助团队基于业务流程创建软件组件和服务并且加快新产品推向市场的时间。领域驱动设计是SOA架构的一个关键元素因为它帮助封装业务流程和规则到一个领域对象中。领域模型也提供了语言和上线文,根据它服务契约能够被定义。
SOA的花费包含领域模型的设计和实现如果它还不存在的话。如果我们过度强调SOA的服务而忽略领域模型的重要性,我们最终将会得到一个充斥着贫血模型和泛滥的服务的应用架构。
完美的场景是DDD的精力应伴随着开发应用层和SOA组件的同时来实现,因为这些是领域模型元素的直接消费者。随着丰富的领域实现,SOA设计也变得相对简单通过提供访问领域对象的外壳(代理)。但是如果我们花费太多精力在SOA层而不关注背后的合适的领域模型,业务服务将是一个不完整的领域模型,带来一个脆弱的SOA架构。