包阅导读总结
1. 业务复杂度、系统设计、治理方法、降低复杂度、优化重构
2. 本文主要探讨业务复杂度,介绍了其定义、分类、影响及原因,重点阐述了降低业务复杂度的方法和优化重构原则。
3.
– 复杂度综述
– 定义:业界无统一定义,斯坦福教授给出复杂度量公式。
– 分类:主要面向业务复杂度治理。
– 影响:研发成本高、稳定性差。
– 业务系统复杂度高的常见原因
– 模块多且关系复杂,互相依赖。
– 大量变化提升开发时间权重。
– 降低业务复杂度的方法
– 抽象分治,分解复杂度,包括领域拆分、领域内拆分、子领域/系统内部拆分、方法逻辑拆分、系统合并。
– 添加注释,使代码易懂。
– 配置化,包括业务对象、业务规则、业务流程可配置。
– 使用规范降低复杂度。
– 业务复杂度优化重构原则
– 小步快跑。
– 先写后读。
– 先轻后重。
思维导图:
文章地址:https://mp.weixin.qq.com/s/sWmE-A15bPzA76wrQnv1NA
文章来源:mp.weixin.qq.com
作者:京东物流??尹昊喆
发布时间:2024/9/5 8:53
语言:中文
总字数:4455字
预计阅读时间:18分钟
评分:91分
标签:业务复杂度,系统设计,软件工程,代码规范,配置化
以下为原文内容
本内容来源于用户推荐转载,旨在分享知识与观点,如有侵权请联系删除 联系邮箱 media@ilingban.com

复杂度综述
理解,首先 MCube 会依据模板缓存状态判断是否需要网络获取最新模板,当获取到模板后进行模板加载,加载阶段会将产物转换为视图树的结构,转换完成后将通过表达式引擎解析表达式并取得正确的值,通过事件解析引擎解析用户自定义事件并完成事件的绑定,完成解析赋值以及事件绑定后进行视图的渲染,最终将
1、什么是复杂度
软件设计的核心在于降低复杂性。–《软件设计的哲学》
业界对于复杂度并没有统一的定义,斯坦福教授John Ousterhout从认知负担和工作量方面给出了一个复杂度量公式
子模块的复杂度cp乘以该模块对应的开发时间权重值tp,累加后得到系统的整体复杂度C
需要注意:如果一个子系统特别复杂,但是很少使用及修改,也不会对整体复杂度造成太大影响。例:spring框架内部代码较为复杂,但由于几乎不需要我们去变动,所以对系统的整体复杂度影响并不大
2、复杂度分类
本文主要面向业务复杂度的治理
3、业务复杂度高的影响
(1)研发成本高。需要花费更多的时间去理解、维护代码;同样的需求,可能需要要修改更多的工程和类
(2)稳定性差。过高的业务复杂度,会导致系统难以理解甚至理解出现错漏,改动代码后极易出现“按下葫芦起了瓢”的问题
业务系统复杂度高的常见原因
理解,首先 MCube 会依据模板缓存状态判断是否需要网络获取最新模板,当获取到模板后进行模板加载,加载阶段会将产物转换为视图树的结构,转换完成后将通过表达式引擎解析表达式并取得正确的值,通过事件解析引擎解析用户自定义事件并完成事件的绑定,完成解析赋值以及事件绑定后进行视图的渲染,最终将
1、什么是复杂度
业界对于复杂度并没有统一的定义,斯坦福教授John Ousterhout从认知负担和工作量方面给出了一个复杂度量公式
2、复杂度分类
本文主要面向业务复杂度的治理
3、业务复杂度高的影响
(2)稳定性差。过高的业务复杂度,会导致系统难以理解甚至理解出现错漏,改动代码后极易出现“按下葫芦起了瓢”的问题
业务系统复杂度高的常见原因
1、业务系统模块多,关系复杂,互相依赖
如下边的业务处理代码,不点进具体的方法,根本不知道做了什么:
public void handleBiz(){
step1();
step2();
step3();
}
再比如下边的业务处理代码,做了方法定义外的操作,开发者很容易遗漏重要信息
public Po convert(Dto dto){
Po po=new Po();
po.field=dto.filed;
mapper.update(po);
XXGateway.update(dto);
return po;
}
大量的变化造成花在系统上的时间增多,提升了开发时间权重;
降低业务复杂度的方法
1、抽象分治,分解复杂度
(1)领域拆分
a、实体类的系统。映射到物理实体,比如商品中心、用户中心、地址服务等
b、流程类系统。映射到多个角色的串联协调工作,比如供应链上单,审核类系统等
供应链领域化拆分例子:
(2)领域之内拆分
01、变与不变拆分。将不易变化的系统能力拆分出来,上层适配各种业务逻辑,底层提供稳定的能力单元。如营销领域,将优惠卡券这个不易变的内容作为一个子系统来设计。
背景:营销域即有面向商家的营销资质、营销活动管理,又有面向C端用户根据活动领红包、优惠券的高频业务
其中,B端业务逻辑较复杂但请求量小,C端业务逻辑较简单但请求量大
治理方案:【变与不变拆分】+【场景BC隔离】
建设营销B端服务。提供面向商家的营销活动管理,重心放在建设复杂的营销活动模型、处理复杂的业务流程;
建设C端用户系统,提供面向C端客户的领营销资产、消费影响资产服务,重心放在高并发、高可用建设;
建设底层营销资产管理服务。如卡券中心提供生成卡券、消费卡券、查询卡券等基础稳定的服务。相对不易变化,不需要经常迭代;
上层的服务根据不同的业务场景来决定把卡券发给谁、什么时候发、发多少,业务场景变化或者有新的场景时,经常需要迭代
背景:
02、技术上。为了提升性能,高频操作场景会先操作redis缓存,再异步同步DB数据
治理方案:抽象业务+变与不变拆分
库存操作业务可以抽象为:根据用户条件、库存划分规则定位到需要操作的库存记录,按照库存记录对库存进行操作
变与不变拆分:01、DB库存操作、Redis库存操作建设为底层支撑能力,仅提供基础的库存加减能力,尽量保障其不变性,避免大幅度的改动影响所有业务 02、根据业务逻辑去定位库存,这部分相对来说变化比较频繁,由上游业务系统进行处理
库存架构如下图:
(3)子领域/系统 内部拆分
01、代码分层。确定每一层的分工;确定调用关系,不能跨层调用;如果下层能解决的复杂性问题,不要放到上层,如:外部接口调用失败重试,不能放到服务层
@Override
public InsertDeptResponse insertDept(InsertDeptRequest request) {
log.error("insertDept request:{}",request);
InsertDeptResponse response=null;
String umpKey = XXX;
Profiler.registerInfo(umpKey, true, true);
try{
checkParam(request);
checkAuth();
response=XXFacade.insertDept(request);
}catch(BizRuntimeException ce){
log.error("XXX");
response=XXX;
}catch (Exception e) {
log.error("XXX");
response=XXX;
Profiler.functionError(info);
}
log.error("insertDept response:{}",response);
Profiler.registerInfoEnd(info);
return response;
}
-
业务逻辑层:整体负责接口中的业务逻辑处理。主要进行各领域间的逻辑串联、数据处理 -
领域服务层:以某个核心概念为核心组件领域服务,如权限服务,将该领域相关能力进行收口,提供给上层可复用的能力
背景:供应链业务中,二维码牌安装服务流程特别复杂,理解与修改都很困难;流程中用到很多数据,在不同方法中被重复获取
结构化分解后的流程:
拆分后主方法伪代码:
public void setUp(){
paramCheck();
initData();
businessCheck();
businessExecute();
}
(4)方法逻辑拆分。职责单一、命名准确
(5)系统合并
2、添加注释,使代码易懂
(1)代码思路要通过注释/自注释标识出来
例:redis模式的库存操作,在处理逻辑主方法中,较为清晰的标注了每一步核心逻辑
(2)注释应当能提供代码之外额外的信息
01、一些不那么直观的代码,可以附上原因
3、配置化
(1)业务对象可配置
(2)业务规则可配置
背景:物流能力中心项目中,要计算不同的仓类型、不同的资源类型(人员、场地、物资、车辆等)、不同履约时效的履约能力,每种场景接入的参数都不一样,计算工时也不一样,算法还经常需要调整,如果使用硬编码的方式,要对几十种业务组合编写业务逻辑,工作量大,维护困难
(3)业务流程可配置
TMF2.0 配置流程:
4、使用规范降低复杂度
(1)代码规范
(2)架构层级规范
例:物流百川三层架构,定义了系统层级,使系统交互有序
3、先轻后重。先做简单逻辑再做复杂逻辑。先迁移轻业务,有了经验后,再去迁移更复杂的重业务
▪功能支撑:会员成长体系、等级计算策略、权益体系、营销底层能力支持
▪用户活跃:会员关怀、用户触达、活跃活动、业务线交叉获客、拉新促活