OOD沉思录3 类和对象的关系--使用关系
类和对象的关系--使用关系原则
4.1 尽量减少类的协作的数量,即减少使用者和被使用者的数量。
协作意味着一定程度的耦合,但是完全没有协作的类也是没有意义的,最多只能作为一个库使用。
通过抽象,依赖接口,可以最大程度减少依赖的实现类,对使用者来说,只看到接口的依赖,而具体的实现的依赖可以通后后期绑定来配置依赖关系。
如 菜单----〉牛肉
----〉羊肉
----〉鸡肉
可以抽象为
菜单---->肉类<===牛肉
<===羊肉
<===鸡肉
其中---->代表使用,<====代表实现
4.2 尽量减少类和协作者之间传递的消息的数量。
4.3 尽量减少类与协作者之间的协作量
即减少类和协作者之间传递不同消息的数量。
4.4 尽量减少类的扇出。
类的消息(方法)数 X 发送的消息(调用其它类的方法)数 = 类的扇出。
使用关系
对象A的方法MethodA使用了B的方法MethodB,则表示A对B存在使用关系
使用关系的最关键问题在于,A如何找到B,存在6种方案
方案一:
A包含了B,B作为一个成员定义在A的类中,那么在MethodA中可以直接调用B.MethodB()
如汽车可以包含车轮。
但是汽车需要加油,那么就需要调用"加油站B.加油()"
- class 汽车
- {
- 加油站 m_加油站;
- 加油(...)
- {
- //调用某加油站的加油方法
- m_加油站.加油();
- }
- }
那么关键问题在于,汽车如何知道加油站X?
如果让汽车包含加油站,肯定不合适,那么还有以下5种方案:
方案二:
通过形参将加油站传递给调用的方法,那么调用形式就是“加油站.加油()",那么汽车的定义则如下
- class 汽车
- {
- 加油(加油站 X)
- {
- X.加油();
- }
- }
方案三:
通过一个第三方类来获得加油站,如地图类,则汽车的定义如下:
- class 汽车
- {
- 加油()
- {
- 加油站 X=地图.查找一个加油站();
- X.加油();
- }
- }
方案四:
全世界只有一个加油站,那么所有的汽车都到这里来加油,则汽车的定义如下:
- class 汽车
- {
- 加油()
- {
- 加油站.TheInstance.加油();
- }
- }
这种情况就是单件模式的例子,还记得它吗?
方案五:
对款爷来说,随时修一个加油站,加完油就推平,这种情况在大部分领域行不通(代价太高),但是在软件领域可以(因为代价很低)
这种情况下,汽车的定义如下:
- class 汽车
- {
- 加油()
- {
- 加油站 X=new 加油站();
- X.加油();
- delete X;
- }
- }
方案六:
汽车制造商在汽车的玻璃上明确标注了,此车只能在名叫"XX加油站",则汽车的定义如下:
- class 汽车
- {
- string 加油站名="XX加油站";
- 加油()
- {
- 加油站 X=企业黄页.查找(加油站名);
- X.加油();
- }
- }
这种方案,在有的地方叫弱引用,汽车并不直接包含加油站,但是包含加油站的一个标示