领域驱动设计_01_基本概念
一、前言
二、领域、子域、限界上下文
1.领域
2.子域
核心域、支撑子域、通用子域
3.限界上下文
(1)边界
限界上下文是一个显示的边界,领域模型边存在于这个边界之内。
在边界内,每一个概念模型,包括其属性和操作,都具有特定的含义。
(2)概念命名
在一个上下文中,团队通常根据通用语言来命名某个概念。
比如两个银行上下文,一个用于支票账户,一个用于储蓄账户。在支票上下文中,我们不必使用 checking account ,也不必在储蓄上下文中使用 saving account ,两个概念都可以使用账户 account 来表示。
4.问题空间和解决方案空间
在领域中还同时存在着问题空间和解决方案空间
-
问题空间
问题空间是领域的一部分,对问题空间的开发将产生一个新的核心域。对问题空间的评估应该同时考虑已有子域和额外所需子域。
因此,问题空间是由战略核心域及其支撑子域组成
-
解决方案空间
解决方案空间包括一个或多个界限上下文,即一组特定的软件模型。
三、上下文映射图
两种表示方式:
- 简单框图
- 源码实现
1. 9种DDD组织和集成关系
- 开放主机服务
- 发布语言
- 防腐层
2.示例图
四、架构
1. 一个成功案例的架构演进
1.1 SAAS的订阅模型
1.2 六边形架构
1.3 SOA
通过SOA的方式来聚合数据
1.4 CQRS架构
1.5 事件驱动架构
使用管道和过滤器模式实现
1.6 优化1
将管道和过滤器分布化和并行化,这需要加入长时处理过程,有时也加入Sagas.
1.7 优化2
跟踪对系统的每一次改变,采用事件源(Event Sourcing)
2. 分层架构
2.1 分层架构图
分层架构模式被认为是所有架构的始祖。
在分层架构中,我们将领域模型和业务逻辑分离出来,并减少对基础设施、用户界面甚至是应用层逻辑的依赖,因为他们属于不同的业务逻辑。将一个复杂的系统分为不同的层,每层都应该具有良好的内聚性,并且只依赖于比其自身更低的层。
- 用户接口层 : User Interface
- 应用层:Application Layer
- 领域层:
- 基础设施层:Infrastructure Layer
2.2 分层架构原则
分层架构的一个重要的原则是:每层只能与位于其下方的层发生耦合
2.3 分层架构种类
分层架构分类:
- 严格分层架构
某层只能与直接位于其下方的层发生耦合。- 松散分成架构
允许任意上方层与任意下方层发生耦合。由于用户界面层和应用服务通常需要与基础设施打交道,许多系统都是基于松散分层架构的。
2.4 用户界面
用户界面只用于处理用户显示
和用户请求
,可对用户输入进行校验
,不应该包含领域或业务逻辑。
如果用户界面使用了领域模型中的对象,那么此时的领域对象仅限于数据的渲染展现。在采用这种方式时,可以使用展现模型(Presentation Model)
,对用户界面和领域模型进行解耦。
由于用户可能是人,也可能是其他的系统,因此有时用户界面层将采用开放主机服务
的方式向外提供API
2.5 应用服务
应用服务(Application Service)位于应用层中。
应用服务和领域服务(DomainService)是不同的,因此领域逻辑不应该出现在应用服务中。
应用服务可以用于持久化事务
和安全认证
,或者向其他系统发送基于事件的消息通知
,另外还可以用于创建邮件
以发送给用户。
应用服务本身并不处理业务逻辑,但它却是领域模型的直接客户。
应用服务是很轻量的,它主要用于协调对领域对象的操作,比如聚合
聚合的最佳实践
:
当需要创建新的聚合时,应用服务应该使用工厂或聚合的构造函数来实例化对象,然后采用资源库对其持久化。应用服务还可以调用领域服务来完成和领域相关的任务操作,但此时的操作应该是无状态的。
存储和转发事件:p106
资源库接口实现放在应用层中:
在分层架构中,领域层或多或少地需要使用基础设施层。这里我并不是说核心的领域对象会直接参与其中,而是说领域层中的有些接口实现依赖于基础设施层。比如资源库接口的实现需要基础设施层提供的持久化机制。
还有更好的方法,参见下文的依赖倒置原则。