架构设计是基于架构原则和目标给出问题解决方案的过程。架构和设计遵循相同的原则和方法,只是解决问题的规模和层次不同,而这规模和层次没有明显界限。
动静分离,高内聚,低耦合
web项目前后分离两大阶段:
单体架构问题:代码耦合不适合迭代更新、更新部署影响大、大型项目开发困难、项目启动慢可用性下降、扩展性不好
分层架构模式里的组件被分成几个平行的层次,每一层都代表了应用的一个功能(展示逻辑或者业务逻辑)。尽管分层架构没有规定自身要分成几层几种,大多数的结构都分成四个层次:展示层
,业务层
,持久层
,和数据库层
。如下图:
外圈的层次可以依赖内层,反之不可以;内圈核心的实体代表业务,不可以依赖其所处的技术环境。
六边形架构又称“端口和适配器模式”,是Alistair Cockburn提出的一种具有对称性特征的架构风格。在这种架构中,系统通过适配器的方式与外部交互,将应用服务于领域服务封装在系统内部。
六边型的适配器类似于反腐层的概念。
反腐层(Anti-corruption layer,简称 ACL)介于新应用和旧应用之间,用于确保新应用的设计不受老应用的限制。是一种在不同应用间转换的机制。
命令查询的责任分离Command Query Responsibility Segregation Command和Query数据源分为同构和民构两种,读写分享是这种架构的一种简单实现。
从事务的角度来看 CQRS,需要面对的问题从根本来说是个最终一致性的问题。
异步、高度解耦
DDD为两类方法论的实践集合:
DDD的过程:Why->What->How
问题域
:核心领域、子领域、限界上下文、上下文映射
核心为限界上下文,基本与微服务可以对应上。
重点:具备唯一ID,是否是同一实体比较ID,能够被持久化,具有业务逻辑
重点:不具备唯一ID,是否是同一对象比较值是否相同
值对象的定义是:描述事物的对象;更准确的说,一个没有概念上标识符描述一个领域方面的对象。
重点:大部分的聚合都只是一个实体,该实体同时也是聚合根,并不是所有的实体都是聚集根,但只有实体才能成为聚集根。
一个聚合是一组相关的被视为整体的对象。每个聚合都有一个根对象(聚合根实体),从外部访问只能通过这个对象。根实体对象有组成聚合所有对象的引用,但是外部对象只能引用根对象实体。
基于聚合的以上概念,我们可以推论出从数据库查询时的单元也是以聚合为一个单元,也就是说我们不能直接查询聚合内部的某个非根的对象;
服务这个词在服务模式中是这么定义的:服务提供的操作是它提供给使用它的客户端,并突出领域对象的关系。
所有的service只负责协调并委派业务逻辑给领域对象进行处理,其本身并真正实现业务逻辑,绝大部分的业务逻辑都由领域对象承载和实现了。
当一个领域操作被视为一个重要的领域概念,一般就应该作为领域服务。服务应该是无状态的。
工厂用来封装创建一个复杂对象尤其是聚合时所需的知识,作用是将创建对象的细节隐藏起来。客户传递给工厂一些简单的参数,然后工厂可以在内部创建出一个复杂的领域对象然后返回给客户。当创建 实体和值对象复杂时建议使用工厂模式。
仓储是用来管理实体的集合。
仓储里面存放的对象一定是聚合,原因是domain是以聚合的概念来划分边界的;聚合作为一个整体概念,要么一起被取出来,要么一起被删除。外部访问不会单独对某个聚合内的子对象进行单独操作。因此,我们只对聚合设计仓储。
respositories和dao:
dao是面向数据访问的,是关系型数据库和应用之间的契约。
repository:位于领域层,面向aggregation root。repository是一个独立的抽象,使用领域的通用语言,它与dao进行交互,并使用领域理解的语言提供对领域模型的数据访问服务的“业务接口”。
如果我们能把设计做到极致,它就能成为一门语言,一门解决一个特定问题的语言。
01->Assembly->c->GPL (Generalized Programming Language)->DSL
01->Assembly->c->Lisp->DSL
常见DSL:
HTML、CSS、MAVEN、sql
我们通常所用的中间件框架实际上就是一种内部 DSL:
Spring、spring mvc、springboot、mybatis
Lisp 的本质:https://www.iteedu.com/blog/plang/lisp/lispdiary/lispbz/
Lisp之根源:https://www.iteedu.com/blog/plang/lisp/lispdiary/lispzgy/