面向对象度量简介
原文地址:http://agile.csc.ncsu.edu/SEMaterials/OOMetrics.htm
<略去第一部分说明>
2 度量分析
以面向对象度量来分析代码时,经常使用CK(Chidamber Kemerer)度量集[8] 和MOOD [1,2]度量集。 在本节中,我们将列举和解释度量指标的具体运用。
2.1 耦合
1974年,史蒂文等人在结构化编程的背景下首先定义了耦合为“模块间关联强度的指标[21] “。而对于面向对象开发, 耦合是两个对象间相互依存关系的指标。例如,如对象A和呼叫对象B的一个方法或者访问它的一个属性,那么这两个对象就是耦合的。
耦合指数(CF)是一个分数式。 分子表示非继承对象间的耦合的数量。 分母是系统中的耦合对象的总数。 耦合对象的总数既包括继承对象间和非继承对象间的耦合。 基于继承的耦合出现在派生类(子类)访问基类(父类)的方法和属性。 CF度量包括在MOOD度量套件中。
实验数据支持对象之间低耦合的好处 [6,7,20] 。 其主要论据是,软件构件之间的耦合越强,( i )越难于了解单个组件(工件,artifact),以正确地维护或加以改进;(ii)各组件对于意外的变化和缺陷影响的敏感性越来越大; 以及(iii)因此需要更多的测试,以达到令人满意的可靠性。 此外,对象之间的过度耦合是有违于模块化设计的,也不利于复用。 总之,低耦合才是可取的。
2.2 内聚
内聚是指类各操作如何紧密相互关联。 一个类的内聚,可以表示类的内部操作与其实例变量相关联的程度。CK度量集会LOCOM(方法中缺少内聚指数),它是指访问一个或多个相同属性的方法数量 [12] 。若没有方法访问相同的属性,则其值为0。
有至少两个不同的方法度量内聚:
- 一类是为每个数据字段计算出使用此数据字段的方法所占总方法数的比例。 然后取平均值,并用100%减去它。 较低的的百分比的表示更好的内聚。
- 如果方法访问相同的属性,它们必定相似的。 计算方法使用的属性交集产生的不相交集合的数目。{
译注:什么是不相交集呢?点这里. 这里的表述太过复杂了。参考<<软件工程>>中的描述,如一个类具有6个方法,其中4个方法有一个或多个属性是相同的(它们使用共同的属性),那么LOCOM=4,其内聚度量指标则为2 (6-4)。}
高内聚显示了良好的类功能的细化{译注:比较符合单一职责原则}。 缺乏内聚或低的内聚将增加类的复杂性,从而增加在开发过程中出现错误的风险。 内聚低的类或许可以再被细分成两个或两个以上的子类以增加内聚。 这个度量指标可以评估设计实现以及可重用性。
2.3 封装
信息隐藏是一种设计常规,例如,只有一个模块的用户只能了解该模块的公共接口。 信息隐藏在面向对象的语言中就体现为”封装”。 “封装意味着所有的对象能被看到的就是它的接口,即对象能被执行的操作[17]”。 信息隐藏是一种技术理论,并且在实践中无可争议地证明了它的价值。研究发现,运用信息隐藏的大型程序在易于修改上,4倍于没有运用此技术的程序[参4,18]。
以下两个是包含在MOOD中的封装度量方法。{译注:属性可以理解为成员变量。}
2.3.1 属性隐藏因子(AHF)
属性隐藏因子测试类中的不可见(invisibility)的属性。 属性的不可见(invisibility)是指不可访问该属性的类所占的百分比。 注意,如果可以通过另一个类或对象访问这个属性,那么这个属性也被视为可见。 属性应该是“隐藏”在一个类内。 他们可以被声明为私有以保持隐藏性。
属性隐藏因子是一个分数式。 分子是在所有类中不可见属性的数量总和。 分母是在项目中各个类中定义的属性数量总和[10]。 这个因子越大越好。
2.3.2 方法隐藏 因子(MHF)
属性隐藏因子测试类中的不可见(invisibility)的方法。 不可见的方法是指不可访问些方法的类所占的百分比。
同样,方法隐藏因子也是一个分数式,分子是在所有类中不可见方法的数量总和。 分母是在项目各类中定义的方法的总数。
方法应封装(隐藏)在类内部且不能为其他对象使用。 方法隐藏能提高在其他程序中的复用性,并且降低复杂度。 如果要改变某一方法的功能,在没有隐藏此方法的情况下,所有访问该方法的对象都会受到影响。 因此,方法隐藏也可减少代码的修改[10]。 这个值也应当越大越好。
2.4 继承
继承通过减少方法数量来降低复杂度, 但这种对对象的抽象却带来维护和设计的困难。有两个指标用来衡量继承层次结构的深度和广度。
2.4.1 继承深度(DIT)
继承深度被定义为类层次结构中的由根节点到子类结点的最大长度。 在涉及多重继承的情况下,DIT是指从根结点到叶子结点的最大长度 [8] 。
结构良好的面向对象的系统有一个类的森林结构,而不是一个大的继承结构。 一个类的层次越深,它所继承的大量方法使得预测其行为变得更为复杂,因此,更容易出错 [15]。 深层次的继随树带来更大的设计复杂性,因为涉及众多的方法和类 [8] 。 事实上,深层次也是概念完整性的一个困扰,因为难以确定哪个类是某个特定形式 [3] 。 此外,在继承树中的接口变化必然反映到整个继承树和相关的对象实例中。 但是,深层次的继承树对于继承的方法反而有更大重用性 [8] 。
如果有太多类靠近根结点,应用程序可以被认为是“头重脚轻”,也表示无法获得因为继承方法而获得方法复用的好处。 另外,应用程序也可以通过增加类层次结构中底部的类,而变成“金字塔型”结构,从而造成设计复杂性和概念完整性的困扰。
2.4.2 子类数量(NOC)
这个指标是每个类的直系子类的数量。 拥有大量子类的类是很难修改的,通常需要更多的测试,因为一处修改将影响所有子类。 他们也被认为是高复杂度且高缺陷的,要为大量场景提供服务,必须更加灵活 [3] 。
2.5 复杂度
2.5.1 类的加权方法(WMC)
WCM衡量单独一个类的复杂度。 拥用更多成员函数的类通常被认为是更复杂的,因此更容易出错 [3] 。 在一个类中的的方法越多,对子类的潜在影响也越大。类的大量方法可能是的具体应用,并且限制了代码复用的水平。 所以,较少的方法对设计的可用性和复用性都有好处。
然而,最近的软件开发的趋势是支持有更多的、更小的方法,取代更少的、更大的方法,以减少的复杂性,增加可读性[13]。这和前面的结论相悖。 目前关于推荐更多、更小的方法的建议已经变得更加审慎。 然而,在一个大的继承结构有众多的方法是绝对不可取的。
通常情况下,认为WMC的计算会考虑各个方法的复杂度{译注:圈复杂度,参另一篇博文}和方法的数量,并可能有不同的权值 [12] 。
{译注:简单一点的就是各个方法的圈复杂度之总和。}
2.6 其它的度量指标
2.6.1 类数
对于相同功能的项目而言,越多的类表示更好的抽象。{译注:并没有实质的意义}
2.6.2 代码行 {译注:最传统的度量指标}
功能相同的项目,越少的代码{译注:不含注释和空白行。},表示更优越的设计以及更少的维护成本。
此外,过大的方法,始终要面对高风险的属性,如可理解性,可复用性以及可维护性。
2.7 度量综述
下表总结了以上讨论的指标, 它表示了在一般情况下,是否是代码质量好所对应的指标值的高或低 {译注:比如低表示越低越好}。 但是,仍然需要在实务中为手上的工作找出哪些项是最适宜的评量指标。
表1:度量汇总表
度量指标 |
取值 |
耦合系数 |
较低 {译注:表示越低越好,下同.} |
方法中缺少内聚指数 |
较低 |
圈复杂度 |
较低 |
属性隐藏因子 |
较高 |
方法隐藏因子 |
较高 |
继承树的深度 |
低(折衷) |
子类数 |
低(折衷) |
类的加权方法 |
低(折衷) |
类数 |
较高 |
代码行 |
较低 |
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/161252.html