首先说明,在这里我把“关联”、“组合”、“聚合”关系都统一当做“组合”关系来说的,但实际上聚合(has-a)是关联的一种,组合(cntains-a)也是关联的一种。如果想要知道三者之间的区别,详见这篇博客:
组合关系直接把类B的实例作为自己的成员变量,意思是我拥有了它,它必须作为我必不可而少的部件。
依赖关系只是在自己的成员方法中用到了类B,意思是我使用了它,但我不一定拥有它。
还是拿【司机】和【车】来举例。
如果采用组合关系,意思是,“我有一辆车,这辆车是我的了,我开我自己的车”
class Car{
public void run(){
System.out.println("在跑了在跑了");
}
}
class Driver{
Car myCar; //这辆车是我的
public void drive(){
myCar.run();
}
}
如果采用依赖关系,意思是“我开走了一辆车,但这辆车不一定是我的”
class Car{
public void run(){
System.out.println("在跑了在跑了");
}
}
class Driver{
public void drive(Car car){ //这辆车不一定是我的,反正我开跑了
car.run();
}
}
在实际开发中如何选择用依赖关系还是组合关系呢?
答案是whatever!
理论分析:根据耦合性有强到弱的关系:继承∣实现→组合→聚合→关联→依赖
因为组合关系比依赖关系的耦合性更强,这也就要求我们能用依赖关系就不要用组合关系,
但有的时候类B必须作为类A的一个部件(类A必须拥有类B),就得用组合关系了(见策略模式中Duck和Character的例子)。
举一个更贴切的例子,Person类和Arm类就必须是组合关系,因为一个人必须有自己的胳膊,不能说我用胳膊实现抬手这个动作的时候就通过形参随便拿别人的胳膊用一用。
实际开发:貌似使用组合关系比使用依赖关系带来的耦合性并不大,所以基本上都用组合,比如观察者模式的例子里,明明可以用依赖关系,却选用了组合关系,因为毕竟拥有了这个类(将其作为成员变量)才能方便地在所有成员方法中操作它。