概念及说明理解
领域
领域与具体开发技术无关。就是你的软件系统要解决的实际问题相关的所有东西的集合。
按问题域理解:每个限界上下文专注于解决某个特定的子域的问题,限界上下文可以理解为问题空间(Problem Space),随着设计和含义的清晰化,限界上下文会迅速的转换为解决方案空间(Solution Space)
非常结构清晰的一张图
领域的整体概念图
限界上下文
限界上下文(Bounded context)是一个显式边界(边界:通常是一个子系统或者一个特定团队的工作),领域模型存在于边界之内。建立模型过程中形成了通用语言,通用语言在特定上下文中才有明确的意义。
限界上下文书语义和语境上的边界,用于表达其边界内的软件模型。在限界上下文内的软件模型有着特定的含义并且在处理独特的事务。
按团队工作理解:一个团队应该在一个限界上下文中工作,根据组织大小可能对应一个大部门也可能对应一个小团队,如果是大部门,则小团队围绕着子域/聚合工作。
上下文映射图
限界上下文之间会互相集成,这种集成关系称为上下文映射
上下文映射图不是一种企业架构,也不是系统拓扑图,他是梳理限界上下文的重要手段,可以用upstream和downstream这种关系来形容,也可以用其他方式。
在DDD中存在多种组织模式和集成模式,如下。
1、 合作关系
2、共享内核
3、客户方和供应方开发
4、遵奉者
5、防腐层, 简称ACL
6、开放主机服务,简称OHS
7、发布语言,简称PL
8、另谋塔路
9、大泥球
待跟进——上下文映射设计工具,有必要学习和实践
核心域
当限界上下文被当作组织的关键战略决策进行开发和运维,则这部分软件模型上核心域,核心域是当下或者未来一段时间企业的主航道,因为企业战略不是一成不变的,核心域也是动态调整的。
核心域的识别是一个持续精炼的过程,从一堆混杂在一起的组件中提炼出最重要的内容。——舍九取一的能力
核心域虽然只是一个逻辑概念,但是它体现了重视度关注度,体现了资源的倾斜,架构设计中要清晰的识别出核心域,并确保在执行中能够把最好的资源投入到核心域中。
子域
子域是领域更细粒度的划分,根据重要性与功能将领域分为大致三类(视项目实际情况而定)的多个子域,分别是核心子域、支撑子域和通用子域。核心域是业务成功的主要促成因素,主要竞争力,支撑子域是支撑核心域的,而通用子域是业务系统的公用部分。
核心域
同上
支撑域
系统非核心业务,支撑性质的问题域
支撑子域不需要过度的考虑可拓展性和兼容性,可重用性并非技术着力方向,可替代性才是,我们需要对支撑子域有着明确的契约规范和业务约束条件。
通用域
可以公共复用的问题域
领域模型
限界上下文是一个显示的边界,在边界内部的软件模型的表达就是领域模型,领域模型由模块、聚合、领域服务组成。
战略设计
主要从业务视角出发,建立业务领域模型,划分领域边界,建立通用语言的限界上下文,限界上下文可以作为微服务设计的参考边界。
领域设计的工作方式
在战略层面,DDD非常强调针对业务问题的分析和分解,通过识别核心问题域来降低分析的复杂度。在战术层面,DDD强调通过识别问题域里的不同业务上下文来进行面向业务需求的组件化。最后在实现层面利用成熟的技术模式屏蔽掉技术细节的复杂度。
战术设计
聚合
领域事件
领域服务
聚合根
聚合根是实体,有实体的特点,具有全局唯一标识,有独立的生命周期。一个聚合只有一个聚合根,聚合根在聚合内对实体和值对象采用直接对象引用的方式进行组织和协调,聚合根与聚合根之间通过 ID 关联的方式实现聚合之间的协同。聚合根的主要目的是为了避免由于复杂数据模型缺少统一的业务规则控制,而导致聚合、实体之间数据不一致性的问题。首先它作为实体本身,拥有实体的属性和业务行为,实现自身的业务逻辑。其次它作为聚合的管理者,在聚合内部负责协调实体和值对象按照固定的业务规则协同完成共同的业务逻辑。
实体
值对象
命令
命令(Command):是执行者发起的操作,构成要件是执行者和行为
MVP(Minimun viable Product)
MVP(Minimum Viable Product),最小可行性产品,是研发新产品过程中常用的一个名词,意指恰好满足目标用户核心需求的最简形式产品。
BDD-行为驱动开发(behavior-driver-development)
行为驱动开发是一种敏捷软件开发方法,它鼓励软件项目中的开发者、测试和业务人员之间的协作,包括验收测试和客户测试驱动等实践。实例化需求(Specification by Example)也是一种用于定义软件产品的需求和面向业务的功能测试协作方法,它和行为驱动开发表达的是同样的概念,采用的也是同样的实践。
行为驱动开发是在需求梳理阶段对TDD测试驱动开发的响应,体现在测试验收方面,验收测试通常指面向业务(用户)的(功能)测试,因此它还承载着限界需求说明和测试代码的职责。验收测试最好使用业务人员、开发人员、测试人员都能理解的“语言”来描述,尽可能避免需求理解的偏差。在敏捷开发中,我们推荐使用用户故事中的验收条件来描述需求,采用自然语言和“假如/当/那么”(Given/Wher/Then)的固定格式。
架构边界清晰的好处之一是测试聚焦,让测试聚焦某区域,某层次的测试而开展测试治理
思考与理解
- 动态变化,领域模型动态变化
- 主权意识的思考:领域设计强调领域的限界上下文内的主权意识,团队要承担起主权的捍卫者
- 软件的模型会随着业务的增长持续的打破边界,走向混乱,持续的领域设计是在做混乱的治理,反熵增的,一套面向领域的软件研发体系,大家按照领域独立工作,并且对抗混乱,即系统可以自带垃圾清理机制,增加系统的可持续性。
- 一个对象在不同的业务场景都用应用,在这种情况下,应当按业务场景(上下文)将对象分散其中,而不是用一个对接去贯穿所有业务场景。——这里可能是领域设计与面向对象的区别,或者说领域设计是在业务边界内的面向对象设计。见《领域设计精粹》23页
- 边界清晰的好处之一是测试聚焦,让测试聚焦某区域,某层次的测试而开展测试治理
参考资料:
https://insights.thoughtworks.cn/tag/domain-driven-design/