领域驱动设计(DDD)这本书主要是讲抽象概念、理念、思想,具体可以有不同的实现,具体明确一些尺度或者细节。
第一章 消化知识
这一节主要讲了作者开发一个用于印刷电路板(PCB)的软件工具的过程。
他请教了相关专家,逐步建模。
涉及到的角色:
软件开发工程师、业务方
涉及到的过程:
需求分析、提炼模型
消化PCB相关的业务知识、
形成业务方和开发工程师都能看懂的共同语言/名词(类似于DSL)
我的理解是相当于产品做需求分析的那步,由程序员直接参与,快速迭代讨论形成DSL,省得吃产品理解的二手需求经常出错。
DSL相关:
1.4节还提到用策略设计模式来写代码,让需求方也能看懂代码中运用的策略(可读性),让DSL范围扩散到架构图和顶层代码。
第二章 语言的使用
按我理解还是要形成DSL,图简略。
语言精简程度=>大量使用短语。
第三章 绑定模型和实现
模型和实现要对应,不然就难以维护实现,模型失去意义。
推荐了一下面向对象编程。
建模与代码实现不能完全分离。
第二部分 模型驱动设计的构造块
设计原则:职责驱动
(SOLID原则)
模型驱动涉及到的几个构造块的概念:Service
: 服务;Entity
: 实体,可以理解成数据库中的一张表;Value Object
: 值对象,传输中的不可变对象,为了明确不可变的特性;Factory
: 工厂;Reposity
: 负责隐藏存储层细节;Aggregate
: 负责封装多组VO/实体,聚合;(有说法这个不是某个类,而是一个虚拟概念)Aggregate Root
: 一个实体,作为网关服务,修改生成Aggregate,服务给外界.(我理解就是粗粒度封装entity,减少整个领域的接口数量、暴露在外的引用数量)
领域外的术语:DTO
: 和VO太像了; 但不在领域驱动的语境里;POJO
: 纯粹属于语法语境了;
第四章 分离领域
分离领域,也就是分层架构,然后重点是把领域层分离出来。
ddd的四个概念层:
- UI层/表示层: view
- 应用层: 尽量薄,按我理解就是controller
- 领域层/模型层: 业务概念、状态、规则(按我理解就是logic)
- 基础设施层:持久化、消息传递、UI渲染
层之间松散连接、单向依赖。
如果下层要调用上层: 回调、观察者模式。
不要把所有东西都放到applicationContext
里头,只放助于解耦的部分。
这个是出于性能考虑,毕竟spring是用一个concurrentHashMap
作为Ioc容器的。啥都往里头奔放了。
(可以只放大粒度对象。
smartUI: 就是在UI代码里写很多逻辑,巨复杂不好维护。不推荐。
第五章 软件中所表示的模型
Entity
: 实体,可以跨实现跟踪,(可以在数据库中查到).Value Object
: VO
, 仅用于传输,是某个状态的镜像,不可变。Service
: 服务,只封装方法,无状态,可以放心调用。粒度中等为好。
简化关系
遇到多对多、双向关联关系,可以寻找自然偏向,从而把它简化为:1对多,单向关联。
例子:
一般问美国1790年的总统是谁,而比较少问华盛顿
是哪个国家的总统。
所以国家和总统的关系可以简化为单向。
第六章 领域对象的生命周期
Aggregate
根/Aggregate Root
: 汽车Entity
边界内实体/Entity
: 轮胎
Aggregate
外部只引用根。(利于垃圾收集)
边界内其他实体以Value Object
形式交付给外部。(不可变,利于修改可控,修改由根控制,保证一致性)
Factory
创建对象或Aggregate工作很复杂的时候,可以引入Factory来封装。
Factory的设计模式包括:
简单工厂: 对字符串switch case;或传入类名,反射创建对象;
工厂: 不把所有创建放一个类,每个类有自己的工厂,巨啰嗦;(符合开闭原则,用冗余来获取简单)
抽象工厂
Builder模式
Factory的作用:
- 把和运行时工作无关的复杂创建逻辑抽离到别的地方;
- 解耦两个类的关联:(跨Agg边界的两个类) 比如需要用账号类创建交易对象,但是本质上账号对象和交易对象关系比较弱,可以用工厂来创建,这样耦合度低一些。
防止Factory的滥用导致类膨胀,正常情况直接用构造函数。
Factory还可以负责反序列化,重建对象。
Repository
封装对数据的访问,方便随时切换底层实现(内存哑实现、缓存)
事务
repository
不封装事务,事务的决定权留给调用方。
Factory vs Repository
Factory
: 生命周期的开始(Entity的创建);Repository
: 生命周期的中间和结束(从数据库查出数据重建Entity不算新建).