先介绍合成/聚合复用原则:尽量使用合成/聚合,尽量不要使用类继承。
聚合:一种弱的拥有关系,体现A对象可以包含B对象,B对象不是A对象的一部分
合成:一种强的拥有关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样。
优先使用对象的合成/聚合,而不是继承。继承是一种请耦合结构,父类变,子类就必须变。
合成/聚合是松耦合结构,有助于将每个类都封装起来,减小类和继承层次规模。
桥接模式:将抽象部分和它的实现部分分离,使它们都可以独立变化。
抽象与实现分离的意思是抽象类和派生类用来实现自己的对象。
即实现系统可能有对角度分析,每一种分类都可能变化,那么就把这种多角度分离出来让它们独立变化,减少它们之间的耦合。
比如我们有各种品牌的手机,手机上装了各种软件。如果我们以手机为抽象类,派生出各种具体品牌手机,再派生出对应的各种软件。如果我们要添加个软件,就得去各品牌手机类下添加。如果要添加个手机品牌,那么不但要去手机抽象类下新派生一个,还要派生出各种软件类。可以看出,派生这种方法耦合度非常高,不易修改。
但是如果我们将各个类封装,由于手机品牌包含软件,但软件不是品牌手机一部分,所以它们是聚合关系。将手机和软件独立出来。这样如果要修改品牌或者软件,都不会影响其它类,具体操作时再将它们聚合在一起。
软件抽象:
public abstract class HandSetSoft {
public abstract void run();
}
具体软件:
public class HandSetGame extends HandSetSoft {
@Override
public void run() {
System.out.println("运行手机游戏!");
}
}
public class HandSetAddressList extends HandSetSoft {
@Override
public void run() {
System.out.println("运行手机通讯录");
}
}
手机品牌抽象:
public abstract class HandSetBrand {
protected HandSetSoft soft;
public void setHandSetSoft(HandSetSoft soft) {
this.soft = soft;
}
public abstract void run();
}
具体品牌:
public class HandSetBrandM extends HandSetBrand {
@Override
public void run() {
System.out.print("M牌手机:");
soft.run();
}
}
public class HandSetBrandN extends HandSetBrand {
@Override
public void run() {
System.out.print("N牌手机:");
soft.run();
}
}
主程序:
HandSetBrand handSetBrand;
handSetBrand = new HandSetBrandN();
handSetBrand.setHandSetSoft(new HandSetGame());
handSetBrand.run();
handSetBrand.setHandSetSoft(new HandSetAddressList());
handSetBrand.run();
handSetBrand = new HandSetBrandM();
handSetBrand.setHandSetSoft(new HandSetGame());
handSetBrand.run();
handSetBrand.setHandSetSoft(new HandSetAddressList());
handSetBrand.run();
修改手机品牌和软件时只需要修改对相应类,不会对其它类造成影响,符合开闭原则。