一.面向对象中的模块
1.类
模块化是消除软件复杂度的一个重要方法,每个代码片段相互独立,这样能够提高可维护性。在面向对象方法中,代码片段最重要的类,整个类的所有代码联合起来构成独立的代码片段。
模块化希望代码片段由两部分组成:接口和实现~
- 接口:代码片段之间用来交互的协议,包括供接口(供给比人使用的契约) 和需接口(需要使用别人的契约)
- 实现:该协议的具体实施
对于类来说,类的供接口 是所有公共成员变量和成员方法的声明,这些都是可以被别的类直接访问的,代表了类愿意与他人协作的一个协议;类的需接口则是在其实现中使用到的其他类及其相关协议~
2.类之间的联系
耦合是代码片段之间的联系。在面向对象中,对象之间也会发生调用,调用时客户对象向服务对象发送某个消息,从而完成对服务对象的共有成员方法和共有成员变量的访问~
在方法调用方面,两个类的方法之间存在的耦合关系与结构化方法基本一致:数据耦合是最好的,内容耦合、重复耦合和公共耦合是不允许的,控制耦合与印记耦合是可以接受的~
在面向对象方法中,类与类之间还会存在其他复杂的关系:
- 关联:如果某个类关联另一个类,那么它就持有另一个类的引用,则这个类所有的对象都具有向另一个类的对象发送消息的能力~
- 继承:子类可以访问父类的成员方法和成员变量~
二.访问耦合
1.访问耦合的分析
如果类A拥有对类B的引用,则A可以访问B。这就是所谓的访问耦合~
衡量两个类之间的耦合度,除了看它们之间存在的访问耦合关系的复杂度,还得看存在具体访问的次数。访问的次数多,则耦合强,访问的次数少,则耦合相对弱~
在几种访问耦合关系中,隐式访问时需要避免的,例外情况是使用标准库时允许出现级联访问,实现访问是可以接受的,也是必要的,毕竟不可能将所有使用的其他类都作为成员变量或者写为方法的参数~
2.降低访问耦合的方法
- 针对接口编程:一方面要求只访问对方的接口,另一方面要避免隐式访问
- 接口最小化/接口分离原则:将一个统一的接口匹配为多个更独立的接口
- 访问耦合的合理范围/迪米特法则:又被称为最小知识原则具体内容包括:每个单元对于其他的单元只能拥有有限的知识,知识与当前单元紧密联系的单元,每个单元只能和他的朋友交谈,不能和陌生单元交谈;另外,只能和自己的朋友交谈~
三.继承耦合
1.继承耦合的分析
在面向对象方法中,由于又继承关系,父类和子类之间也存在耦合~
膝盖规格、修改实现、精化规格三种类型是不可接受的,精化是心爱是可以接受的也是经常被使用的,扩展是最好的继承耦合,但并非每个继承关系都能达到只扩展不调整的程度~
2.降低继承耦合的方法
- Liskov替换原则:又被称为里氏替换原则,内容为子类型必须能够替换带哦类型而起到同样的作用
- 使用组合替代继承:又被称为合成复用原则,既能复用代码,又能保持接口的灵活性
四.内聚
1.面向对象中的内聚
- 方法的内聚
- 类的内聚
- 子类与父类的继承内聚
方法内聚和结构化中的函数内聚一致,主要是体现方法实现时语句之间的内聚性,内聚性由高到底分为:功能内聚、通信内聚、过程内聚、时间内聚、逻辑内聚、偶然内聚
类的内聚主要是衡量类的成员变量和方法之间的内聚,简单地说,类既应该是信息内聚的,又应该是功能内聚的~
2.提高内聚的方法
- 集中信息与行为:高内聚的类应该是信息内聚的,也就是说类的信息应该和访问这些信息的行为放在一个类中
- 单一职责原则:一个高内聚的类不仅要是信息内聚的,还应该是功能内聚的
五.耦合与内聚的度量
为了利用模块化的思想评价设计质量,人们定义了一些量化指标,进行面向对象方法的耦合与内聚的度量
1.耦合的度量
- 方法调用耦合:包括该类调用其他类的成员方法的数量,以及其他类访问这个类的成员方法的数量
- 访问耦合:同济一个类包含的其他类的实力的数量,不包括继承关系带来的实例引用。
- 继承耦合:统计直接所属的子类的数目
2.内聚的度量
LCOM法,计算方式如下: