我一直在想什么才是优秀的业务架构,苦思冥想后只得到了一些正确的废话
- 合适的才是最好的
- 低耦合、高内聚
- 灵活拓展
- 最少的改动满足业务的变化
- 模块化、组件化、可拔插
- 清晰的边界上下文
- 满足业务需求
- 设计模式,简练的代码结构
- …
但是如果在真实的代码开发中,想要的越多,失去的也会越多。
业务架构的核心始终都是对业务系统的设计和构建,首要目标都是满足业务需求。在此基础上根据个人能力或架构师能力为系统注入可扩展性、可维护性、可重用性和灵活性等特性。
随着业务系统的成熟度的变化,对系统设计的要求也随之改变。
项目初期
初期,一个纠结和痛苦的时间点。快速上线的压力和系统设计之间冲突不断。
在我有限的知识储备和项目经验实践中,每个系统都有自己的特色和历史原因,大多数不合理的代码都是向业务妥协的产物,当然也包括程序员个人能力参差不齐的原因。我始终认为程序员思想不能固化,不停地创新才是这个行业进步的方式。当然一个系统内,一些规范还是不能少的,不然代码显得杂乱无章,前后端不停扯皮甩锅。这是一个协商妥协和展现个人能力的过程,言语无法表达,但是制定了规范就要遵守。
回到项目,
- 分析
理解客户(Boss/产品/B端/C端)需求
此时我们不仅仅是程序员,应该切身站在业务的角度上感受需求,明白他们要的是一个什么形态的产品,理解产品价值,判断业务可行性、合理性和替代方案。
监督产品,输出需求文档(被坑过的请举手)。
- 设计
经过对需求的综合分析和技术团队的实际情况,决定适合的架构,或以业务推动技术,抽取公共服务(用户、权限、网关、工作流、等等),独立部署,形成基础服务能力,提升团队研发效率和系统可维护性。
识别业务领域、定义界限上下文、构建反映业务本质的领域模型,这是目前DDD对我最大的帮助。模型的建设
- 编码
什么是DCI 编码?
Data,Context,Interaction 数据在场景中交互
在系统设计时,首先区分数据主体 Data ,分析Data 流转于哪些的业务场景,在每个场景中都有如何的行为。
普通MVC代码是如何调用的
1.Controller
2.Service
3.Mapper
通常会将业务代码放到Service中,做的好的会多写几个Service,将复杂的业务拆分成多个模块相互调用、复用。有点类似 模块聚合、聚合根的概念,限定上下文。但是越来越丰富的交互需求也会变得越来越难理解,**对象的封装会导致内聚性不断增加,交互逻辑会在不同对象之间跳转,对象之间的嵌套关系在复杂系统中无疑是一个理解负担。**简单来说,MVC在简单的业务系统中更有优势。
回到DCI是如何设计的
1.区分数据实体
实体通常是领域模型的核心组成部分,包括业务对象的状态信息。
2.定位业务场景
封装场景下的交互逻辑,上下文负责协调数据实体,将它们置于特定的业务场景,并决定哪些实体应该在场景中扮演何种角色。
3.决定角色
角色确定了特定上下文中数据实体的行为和责任。数据实体在不同的上下文中可以扮演不同的角色,通过动态分配角色的方式,实体临时获得执行特定场景下所需行为的能力。
4.执行交互
交互是特定上下文中角色之间的协同工作和行为(交互是角色行为的组合)。根据场景动态组合行为,而不是将行为硬编码到数据实体中。
- 例如酒店系统中,管理员添加入住人便是一种交互,中间涉及到的
- 数据实体:普通用户,系统用户,酒店订单
- 角色:管理员,入住人
- 上下文:办理入住流程
- 交互:管理员角色在办理入住流程的上下文中,添加了入住人的业务逻辑
所以对交互的定义是,在特定的上下文之间,角色根据职责对数据实体操作,以完成特定的业务逻辑和功能。
首先 DCI 并不适用于简单的业务场景,这样只会增加不必要的设计和研发成本。只有足够复杂的业务场景,才能有区分出不同上下文的必要。
DCI 改进了MVC中模型职责不清、行为分散的问题。以及DDD中模型固定难以适应多变场景的问题、通过将数据与上下文中的角色动态结合,DCI清晰划分职责,使业务逻辑随场景变化灵活切换,提升代码可读性和可维护性。
什么是四层架构?
在实际代码开发中,我习惯使用四层代码结构,每层都有自己的定位和职责。清晰且合理的代码结构,可以让编码变得更加高效,当需要使用什么类方法时可以第一时间定位,代码的可读性和可维护性也得到了保障(聚拢数据修改的入口),每一次变更都变得简单可靠。
-
表现层 Interface
负责处理业务请求,展示信息给客户或对外接口,Controller、API。 -
应用层 Application
负责协调领域和用户界面,处理业务逻辑,接受用户输入,调用领域服务和仓储层完成具体的业务操作。 应用服务类(Application Services)、DTO(用于传递数据到用户界面)、应用服务接口等。 -
领域层 Domain
包含领域模型(Domain Model),负责业务规则和领域逻辑的实现。领域层是DDD的核心,包含实体(Entities)、值对象(Value Objects)、聚合(Aggregates)、领域服务(Domain Services)、领域事件(Domain Events)、领域事件处理器(Event Handlers)。 -
基础设施层 infrastructure
提供通用的技术能力,如数据访问、消息队列、日志、安全等。这一层不应该包含业务逻辑,而是为领域层和应用服务层提供支持。 数据访问对象(DAOs)、数据库连接、消息队列、日志、安全认证、外部服务、防腐接口等。
-| apaas-demo-center
-| apass-demo-api
-| interfaces
-| api -RPC接口暴露
-| dto -RPC接口对象定义
-| apass-demo-service
-| interfaces -用户接口层
-| controller -前端接口暴露
-| vo -对前端对象定义
-| rpc/apiimpl -rpc接口实现
-| converter -dto ,vo 转化器
-| application 应用层,向外提供业务能力的总出入口,多领域之间能力串联
-| command -新增、删除、更新
-| query -查询
-| assembler 组装器
-| mq
-| counsummer
-| provider
-| assember
-| domain 领域层,真正处理业务的地方
-| service
-| impl
-| model -领域内对象
-| enum -枚举
-| constants -常量
-| event -事件
-| infrastructure 提供公共基础服务
-| db
-| converter
-| do
-| mapper
-| dao
-| cache -缓存,所有key的常量值
-| proxy -所有依赖外部服务
-| RPC服务依赖
-| 外部系统依赖
项目中期
项目已经正常展开,很多技术支撑需要落地,如注册中心、项目管理平台、MQ选型、用户中心、网关、日志、流量监控、大数据服务等等。
项目迭代期
日常。
系统重构期
重构单体架构为微服务架构
- 分析出不同的领域,领域下可以包含诺干子领域
- 每个领域界定上下文,确定领域服务
- 领域内明确实体、值对象、聚合、聚合根
- 按照四层代码结构进行代码编写
营销模型
回头再看最初的问题,什么是优秀的营销模型?
-
营销作为一个单独的领域,可以划分成多个子领域
有明确的上下文,所有对外暴露的接口不应该再互相依赖(基础服务除外) -
抽象的数据模型
高内聚数据模型,快速满足业务增加需求 -
合理的代码结构
遵循分层原则和松耦合的设计理念
-
良好的编码习惯
仿佛真的这么简单,哈哈哈