规模复杂度

分而治之,小既是美。

  • Unix设计哲学:单一职责、团结合作
    • 不在老的东西越来越复杂、而是创建一个新的东西完成 → 但是这样的会存在多个小的命令 - 如何分离
    • 每一个命令的输出,变为另外一个新的命令的输入 - 如何合并

结构复杂度

系统 存在 多个 复杂的模块 , 某一个模块里面的代码又是错综复杂,这个时候就是结构复杂度。

清晰直观且易于理解的分层(DIP - 依赖倒置)

首要任务就是确定业务逻辑和技术逻辑的边界。

  • 不关心技术逻辑,而是只关心业务

复杂度 - 横切 、 纵切

横切 - 按照分层:用户接口层、应用层、领域层、基础设施层

纵切 - 业务上 划分

变化复杂度

拥抱变化、只被第一课子弹击中。

分离关注点 - SOC

分而治之 - HTML 、 CSS 、JS

通用语言 - 沟通的标准

客户的需求可能是明确清晰的,也可能是一个想法、需要一起交流才可以确定;

基本上,行业内客户基本都是清晰的、创业的客户基本都是一个想法。 通用语言:消除领域专家和开发者之间的沟通失调

  • 准确、高效、通用
  • 不包含任务IT 术语
  • 只包含术语用例

领域术语:需要明白一个行业的内部黑话

  • 强调动词的准确性 避免:

同名的业务词汇和实际业务关系不清楚

在沟通过程中,需要注意 - 基础咨询问题框架:

  • why:为了什么目的

  • what:要做什么事情

  • who:谁会与此相关

  • when:什么时间做

  • where:在什么地方做

  • how:怎么做

  • how much:需要什么资源

  • exception:例外情况

  • pre - condition: 必须的前提

  • post - condition: 应该的结果 - 与 why 对应

  • “高端客户优惠” 例子

最好是在团队中形成一个相对固定的场景分析模式:

  • 用例图 use case

    文字描述

    图描述 - 这里看一下 include 说明子部分 , extend 说明条件扩展部分

  • 用户故事 - use store

    文字描述 + 验收标准

    用户故事卡 - 短信验证码的例子 - 术语 + 用例

  • 测试驱动开发 - test drive development

    先说需求,然后需求分析优先、任务分解优先

    先写接口,再完成实现

    以一个失败的测试为起点,逐步修复,完成这个单元测试

领域

领域 - 问题的范围

子域:

  • 核心子域: 核心竞争力所在的子域
  • 支撑域:支撑核心域的子域
  • 通用域:服务整个领域的子域

界限上下文:问题的解决方案

  • 界限 Bounded
  • 上下文 Context

动态的业务流程会在边界上进行上下文切换

不同的上下文中,相同的名词的含义可能完全不同。

所以使用界限上下文的概念划分,可以完成消除歧义。

上下文可以区分业务,即可以使用多个表完成业务,而不是一个超大的宽表

界限上下文就是微服务类型的一个指导思想。

可以在划分领域的时候,可以先写出 行为

界限上下文意味着安全、安全意味着可控

界限上下文不仅可以完成技术的边界,也可以完成团队的划分。

“完美的设计不是包罗万象无所不有,而是完整自治、不可精简”

避免出现 “上帝类” ,知道的太多、做的太多、依赖的太多。

上下文映射 - Context Mapping

解决如何联系多个上下文。

上游 U:依赖发起方

下游 D: 依赖上游 团队协作模式:

  • 合作关系

    演化初期的关系,同生共死 , 不是一个很好的协作关系

  • 共享内核

  • 消费供应 - 比较不错 C-S

  • 遵奉者 Conformist

    消费供应的反模式

  • 另谋他路

代码上的上下文关系模式:

  • 防腐层 -ACL

    OCP 的思想设计

  • 开放主机服务 - OHS

    PL - 发布语言,一般结合使用

    上游避免下游的多样性的设计

  • 发布-订阅事件

    吞吐量高、解耦

    但是很难保证一致性。

    如果失败了,基于消息的失败之后,可以基于 SAGA 完成,即基于补偿消息

架构

宏观建模和微观建模衔接的部分 右侧的 DDD 分层设计中 , Application Layer 的作用是什么?

编排业务逻辑:

  • 以前的 业务逻辑层 - 报纸中标题和正文放在了一起 , 流程和细节耦合在了一起
  • 现在加了应用层 , 流程和细节分离; 将报纸修改为杂志;符合单一抽象层次原则。

DDD 分层

现在看看贫血模型: Service 里面承担了所有的逻辑;

要求调用方是一个“全能型”选手,必须知道所有的业务逻辑;

技术和业务相分离:

同时支持输入的多样性

综上,一个DDD分层会去这样设计:

六边形架构 - 整洁架构

按照业务逻辑转一圈,实现一个三色同心圆 ,即一个多层的架构

业务的边界全部是接口,由接口定义好,实现技术和业务分离 , 整体符合 DIP 原则 即依赖注入,技术使用接口挂接进去了

微服务架构

  • 微服务使用界限上下文划分
  • 每一个服务都使用独立的数据存储

CQRS 架构

写模型 和 读模型分离

写的时候可以写窄表,读的时候可以使用宽表 读和写模型可以使用消息等等完成通信;

可能不同的界限上下文可以使用的架构完成。

接下来可以看看一些基础的设计的原则: SOLID