前言
在构建系统的时候,有时候自己会说,我的系统很复杂,但是这时候又遇到问题了,如何度量一个系统的复杂性呢,这个是个开放性的问题,本身答案见仁见智,这里记录一下自己的思考。
历史借鉴
- 算法的复杂度
- 在学习算法的时候,经常会有复杂度的分析,分为时间复杂度和空间复杂度;
- 自我感觉在时间和空间维度,能够比较清晰的表述清楚;
-
代码的圈复杂度
-
概念
-
循环复杂度(Cyclomatic complexity)也称为条件复杂度,是一种软件度量,是由老托马斯·J·麦凯布(英语:Thomas J. McCabe, Sr.) 在1976年提出,用来表示程序的复杂度,其符号为VG或是M。“循环复杂度”的名称有时会让人误解,因为此复杂度不只计算程序中的循环 (循环)个数,也包括条件及分支个数。
-
概要解释,圈复杂度是一种软件度量,重点关注条件和分支个数;
-
-
计算方法
- 计算公式为:V(G)=e-n+2。其中,e表示控制流图中边的数量,n表示控制流图中节点的数量。其实,圈复杂度的计 算还有更直观的方法,因为圈复杂度所反映的是“判定条件”的数量,所以圈复杂度实际上就是等于判定节点的数量再加上1,也即控制流 图的区域数,对应的计算公式为:V(G)=区域数=判定节点数+1。
-
总结
- 总是是计算条件和分支,PMD和checkstyle也有相应的支持,找出高复杂度的代码。
-
分布式系统
- 总体概述
- 总体分多个维度来列举,但是没有统一的公式,因为太复杂了
- 存储复杂度
- 表结构关联关系复杂度
- 数据库表的个数
- 数据库表和表之间的关联关系
- 关联关系可以通过ER图来展现
- ER图的话,可以借鉴圈复杂度,把表抽象为节点,关联关系抽象为路径,套用公式计算
- 数据库表存储维度复杂
- 单表存储
- 分库分表的形式
- 主备模式划分数据库
- 读写分离模式
- 采用类似HBASE的NOSQL形式
- 表结构关联关系复杂度
- 应用工程分层复杂度
- center类应用,仅仅提供SOA的服务
- web和center共同体
- 应用本身的module的划分
- 缓存复杂度
- JVM heap的缓存
- 类似memcache的分布式缓存
- 多级缓存的管理,类似CPU的一级、二级缓存等
- 领域模型复杂度
- 领域核心实体的数量
- 领域核心实体的关联程度
- 领域和子领域的划分
- 物理环境复杂度
- 应用构建的复杂程度
- 例如nginx和tomcat是否能够一键部署
- 是否依赖公共的集群,例如zk等集群
- 在类似阿里云这一类公有云上能否快速部署
- 依赖关系复杂度
- 依赖的外部系统个数
- 依赖的内部系统个数
- 核心业务对于外部系统的依赖
- 外部存储以及缓存的依赖
- 传递依赖的情况
- 多端支撑复杂度
- web端的支撑
- 无线端的支撑
- android系统
- IOS系统
- winCe系统等
- 硬件相关的支撑
- 编程语言的选择
- java编程语言
- js等前端矿建
- C#编程语言
- C++编程语言
- node、go等编程语言
总结
- 总体来看,如果用单一维度考评,应该难度比较大,所以可以从多个维度来进行考评。
PS: 参考文档
- https://github.com/shukai0828/MyTechNotes/blob/master/CodeMetric/CyclomaticComplexity.md
- http://wobfei.iteye.com/blog/706875