面对高复杂度的时候我们会做关注点分离,这是一个最基本的哲学原则。
- 技术维度分离,类似MVC这样的分层思想是我们广泛接受的
- 业务维度分离,根据不同的业态来划分系统,比如按售前、销售、售后划分
微服务的架构更强调从业务维度的关注点分离来应对高复杂度。这是显著区别于传统SOA架构的特质之一,比如诞生于传统SOA时代的ESB(工业服务总线)就是一个典型的从技术关注点分离出来的中间件。
业务和技术渐进统一的架构设计
- 业务架构:根据业务需求设计业务模块及交互关系
- 系统架构:根据业务需求设计系统和子系统的模块
- 技术架构:根据业务需求决定采用的技术及框架
DDD的核心诉求就是让业务架构和系统架构形成绑定关系,这样一来当我们去响应业务变化调整业务架构时,系统架构的改变也会随之发生。这个变化的结果有两个:
- 业务架构的梳理和系统架构的梳理是同步渐进的,其结果是划分出的业务上下文和系统模块结构是绑定的。
- 技术架构是解耦的,可以根据划分出来的业务上下文的系统架构选择最合适的实现技术
第一点显然也是我们产生微服务划分所必须遵循的,因为微服务追求的是业务层面的复用,所以设计出来的系统必须是跟业务一致的。
第二点更是微服务架构的特质:“去中心化”的治理技术和数据管理。
跨职能协作的架构设计
DDD成功运用的基础就是创造让业务和系统这两种不同认知模型逐步统一的环境。
当然刚开始采用DDD方法的时候,请不要认为每个系统搞一次所谓的DDD工作坊就能够找到最佳的服务划分了。业务的变化是持续的,而每次业务架构变化必然牵动系统架构的变化。良好的领域架构绑定了业务和系统,让双方人员能够用统一语言交流,这件事情建立不易,而持续运作更难。
DDD落地为什么这么难
- 统一语言(软件的开发人员/使用人员都使用同一套语言,即对某个概念,名词的认知是统一的)
- 面向领域(以领域去思考问题,而不是模块)
战略设计侧重于高层次、宏观上去划分和集成限界上下文,而战术设计则关注更具体使用建模工具来细化上下文。
限界上下文的划分要注重:核心域(上下文)、支持域(上下文)、通用域(上下文)、每个上下文在系统中都高度内聚。
限界上下文之间的映射关系
- 合作关系(Partnership):两个上下文紧密合作的关系,一荣俱荣,一损俱损。
- 共享内核(Shared Kernel):两个上下文依赖部分共享的模型。
- 客户方-供应方开发(Customer-Supplier Development):上下文之间有组织的上下游依赖。
- 遵奉者(Conformist):下游上下文只能盲目依赖上游上下文。
- 防腐层(Anticorruption Layer):一个上下文通过一些适配和转换与另一个上下文交互。
- 开放主机服务(Open Host Service):定义一种协议来让其他上下文来对本上下文进行访问。
- 发布语言(Published Language):通常与OHS一起使用,用于定义开放主机的协议。
- 大泥球(Big Ball of Mud):混杂在一起的上下文关系,边界不清晰。
- 另谋他路(SeparateWay):两个完全没有任何联系的上下文。
战术建模——细化上下文
实体、值对象、聚合根(由根实体,值对象和实体组成)、领域服务、领域事件
- 实体(Entities):具有唯一标识的对象
- 值对象(Value Objects): 无需唯一标识
- 领域服务(Domain Services): 一些行为无法归类到实体对象或值对象上,本质是一些操作,而非事物
- 聚合/聚合根(Aggregates & Aggregate Roots): 聚合是指一组具有内聚关系的相关对象的集合,每个聚合都有一个
root
和boundary
- 工厂(Factories): 创建复杂对象,隐藏创建细节
- 仓储(Repository): 提供查找和持久化对象的方法
分层可以提供一个相对高层的视角来 分解和简化我们的问题,此外分层也可带来 可测试性、 可维护性、 灵活性、 可扩展性等方面的好处。分层的历史中经典的三层架构(Three-Tier Architecture):展示层(presentation/user interface
)、业务逻辑层(business logic
)、数据访问层(data access
)。然而,其中又存在各种各样的变体,这也给我们的理解造成一定的混乱:
Martin Fowler | Martin Fowler(Detail) | Brown | Core J2EE | Microsoft DNA | Marinescu | Nilsson |
---|---|---|---|---|---|---|
Presentation that runs on client | Client | |||||
Presentation | Presentation | Presentation | Presentation | Presentation | Presentation | Consumer |
Presentation(Application Controller) | Controller/mediator | Application | Consumer helper | |||
Domain | Domain(Service Layer) | Domain | Business | Business | Services | Application |
Domain(Domain Model) | Domain | Domain | ||||
Data source(Data Mapper) | Data mapping | Data access | ||||
Data source | Data source | Data source | Integration | Persistence | Persistence access | |
External resource | Resource |
面对如此多的分层架构,我们不禁思考,他们 分层的依据又是什么呢?在实践中我们又该采取怎样的架构呢?
分层其实是 把一系列相同或相似的对象进行分类并放在同一层,然后 根据他们之间的依赖关系再确定上下层次关系。分层的核心在于 分类 和 关联(事物的两面性: 区别和联系),是不是感觉玩哲学的人更适合做这样的学术研究。
- 分类:确定 划分标准,将相关对象进行 抽象(分离变与不变,提取共同点)并归类,对层之间进行 隔离,并保持层内元素是高度 内聚;
- 关联:层与层以及外部是存在联系的,需要关注不同层间的 依赖与通信,保持层间的 松散耦合
我们可以将系统划分为:
- 较大的 业务 部分:对于业务来说,又可划分为展示的部分(前台)和内部处理逻辑(后台),
- 相对稳定的 技术 部分:
待续