软件量度
主要的软件量度有如下几种:
1、 尺度性指标
代码行数,类成员个数,方法行数:越少越好
类个数:越多越好
2、 结构性指标:
继承深度:继承树的高度
方法加权和:每个方法的环形量度之和(cyclomatic)。简单地说就是条件和循环语句的个数加一。
对象间耦合:一个对象引用的其它类的个数。
类响应集合:一个消息响应可能调用方法的百分比。
方法内聚:一种算法是计算一个类中,百分之多少的方法调用了一个数据成员。百分比越高,内聚越强。
封装性:不可见的成员/方法的百分比。
重构
软件量度可以为重构提供以下帮助:
软件量度可以识别出软件的坏味道。
软件量度可以衡量重构的效率
有很多重构操作也存在着有意义的逆向操作,这意味着需要一种权衡,这时量化量度更有帮助。
操作 | 逆向操作 | 量度变化 |
改名 | 名字的改变对软件量度来说没有影响。 当然名字会影响到可理解性 | |
提炼方法 | 消除方法 | 方法行数发生变化,方法加权和可能变化 通常方法行数减少的时候,重用性会提高,从而降低整个软件的复杂度。 封装性发生变化 设置取值/改值方法 |
引入临时变量 | 消除临时变量 | 代码行数可能变化 改变临时变量的名字可以改善代码的可理解性 方法内聚性发生变化 将成员改成临时变量 |
移动方法/成员 | 提高封装性 有些成员/方法可能变成不可见。 | |
提炼类 | 消除类 | 类的个数,方法内聚性,类成员个数发生变化 这些变化的利弊并不一致,需要加以权衡。 |
改成常数对象 | 改成变量对象 | 类响应集合发生变化 常数对象的行为比较简单,可提高代码的可理解性 |
改成单向关联对象 | 改成双向关联对象 | 对象间耦合发生变化 单向关联的耦合度更小一些 |
分解/合并条件式 | 方法加权和,方法行数发生变化 | |
添加方法参数 | 减少方法参数 | 方法加权和,方法行数可能发生变化 如果引入参数对象,还会带来对象间耦合的变化 如果涉及到参数与成员的转换,方法内聚性也会发生变化 |
添加异常 | 减少异常 | 方法加权和,方法行数发生变化 这里使用异常并不能控制复杂度,相反还可能带来复杂度的增加 |
上移成员/方法 | 下移成员/方法 | 方法内聚性、代码行数发生变化 |
提炼接口 | 方法加权和,对象间耦合发生变化 值得注意的是封装性的变化,一个最小的公共方法集合可以提高封装性。 | |
添加继承 | 减少继承 | 方法内聚性、代码行数,继承深度发生变化 如果可以保证超类/子类行为的一致性,那么添加继承后,方法内聚性会增加。 如果超类/子类行为并不一致,那么减少继承(比如改成委托),方法内聚性也会增加。 |
结语
软件量度是一种量化的,可以自动计算的指标。用于衡量软件重构的效果,可以得到客观的,比较一致的结果。