领域设计
领域驱动设计通常适用于增删改的业务操作,但不适用于分析统计。在一个系统中,增删改的业务可以采用领域驱动的设计,但在非增删改的分析汇总场景中,则不必采用领域驱动的设计,直接 SQL 查询就好了,也就不必再遵循聚合的约束了。
为了让微服务设计做到高内聚,最佳的实践则是 DDD:
- 先从 DDD 开始需求分析、领域建模,逐渐建立起多个问题子域;
- 再将问题子域落实到限界上下文,它们之间的关联形成上下文地图;
- 最后,各子域落实到微服务中贫血模型或充血模型的设计,从而在微服务之间依据上下文地图形成接口。
软件退化
软件退化的根源不是软件变更,软件变更只是一个诱因
开放-封闭原则(OCP)
分为开放原则与封闭原则两部分。
- 开放原则:我们开发的软件系统,对于功能扩展是开放的(Open for Extension),即当系统需求发生变更时,可以对软件功能进行扩展,使其满足用户新的需求。
- 封闭原则:对软件代码的修改应当是封闭的(Close for Modification),即在修改软件的同时,不要影响到系统原有的功能,所以应当在不修改原有代码的基础上实现新的功能。也就是说,在增加新功能的时候,新代码与老代码应当隔离,不能在同一个类、同一个方法中。
杜绝软件退化:两顶帽子
两顶帽子:
- 在不添加新功能的前提下,重构代码,调整原有程序结构,以适应新功能;
- 实现新的功能
保持软件设计不退化的关键在于每次需求变更的设计,只有保证每次需求变更时做出正确的设计,才能保证软件以一种良性循环的方式不断维护下去。这种正确的设计方式就是“两顶帽子”。
单一职责原则
软件系统中的每个元素只完成自己职责范围内的事,而将其他的事交给别人去做,我只是去调用。
总之,单一职责原则要求我们在维护软件的过程中需要不断地进行整理,将软件变化同一个原因的代码放在一起,将软件变化不同原因的代码分开放。
什么是高质量的代码
最直接、最落地的评价标准就是,当用户提出一个需求变更时,为了实现这个变更而修改软件的成本越低,那么软件的设计质量就越高。
领域对象落地数据库
继承关系的 3 种设计
-
使用一个表来记录整个继承关系。在这个表的中间有一个标识字段,标识表中的每条记录到底是哪个子类,这个字段的前面部分罗列的是父类的字段,后面依次罗列各个子类的个性化字段。
-
将每个子类都对应到一个表,有几个子类就有几个表,这些表共用一个主键,即这几个表的主键生成器是一个,某个主键值只能存在于某一个表中,不能存在于多个表中。每个表的前面是父类的字段,后面罗列各个子类的字段。
-
父类做成一个表,各个子类分别对应各自的表。
贫血模型与充血模型
与数据库实体有关的都是贫血模型,比如MVC模式种的实体、DAO、Service。
继承方法实现方法覆盖方法的都是充血模型。
问题域和限界上下文
正确的做法就是将整个系统划分成许多相对独立的业务场景,在一个一个的业务场景中进行领域分析与建模,这样的业务场景称为 “问题子域”,简称“子域”。
领域驱动核心的设计思想,就是将对软件的分析与设计还原到真实世界中,那么就要先分析和理解真实世界的业务与问题。而真实世界的业务与问题叫作 “问题域”,这里面的业务规则与知识叫 “业务领域知识”。
一个复杂系统的领域驱动设计,就是以子域为中心进行领域建模,绘制出一张一张的领域模型设计,然后以此作为基础指导程序设计。这一张一张的领域模型设计,称为“限界上下文”(Context Bounds,CB)。
限界上下文与微服务
所谓“限界上下文内的高内聚”,也就是每个限界上下文内实现的功能,都是软件变化的同一个原因的代码。因为这个原因的变化才需要修改这个限界上下文,而不是这个原因的变化就不需要修改这个限界上下文,修改与它无关。正是因为限界上下文有如此好的特性,才使得现在很多微服务团队,运用限界上下文作为微服务拆分的原则,即每个限界上下文对应一个微服务。