桥接模式
手机品牌M和N都有游戏和通讯录功能,都用继承实现,代码如下.
public class Brand {
public void run() {}
}
public class MBrand extends Brand{
}
public class NBrand extends Brand{
}
public class MBrandGame extends MBrand{
public void run() {
System.out.println("运行M品牌手机游戏");
}
}
public class NBrandGame extends NBrand{
public void run() {
System.out.println("运行N品牌手机游戏");
}
}
//运行M品牌通讯录
public class MBrandAddressList extends MBrand{
public void run() {
System.out.println("运行M品牌通讯录");
}
}
public class NBrandAddressList extends NBrand{
public void run() {
System.out.println("运行N品牌通讯录");
}
}
public class Demo1 {
public static void main(String[]args) {
Brand b;
b=new MBrandGame();
b.run();
b=new NBrandGame();
b.run();
b=new MBrandAddressList();
b.run();
b=new NBrandAddressList();
b.run();
}
}
输出结果为
运行M品牌手机游戏
运行N品牌手机游戏
运行M品牌通讯录
运行N品牌通讯录
刚开始学会面向对象的继承时,感觉它既新颖又功能强大,所以只要可以用,就都用上继承.但事实上,很多情况用继承会带来麻烦.比如上面的代码,如果手机再增加’输入法’,’拍照’,’音乐播放功能’,或者说再增加一个品牌,更改起来会很麻烦.
合成/聚合复用原则
优先使用合成/聚合,尽量不要使用类继承.因为继承是一种强耦合的结构,父类变,子类就要变.所以我们在用继承的时候,一定要在”is-a”的关系时再考虑使用,而不是在任何时候都用.
聚合表示一种”弱”的拥有关系,体现了A对象可以包含B对象(比如雁群包含大雁),但是B对象不是A对象的一部分;合成是一种强的拥有关系,体现了严格的部分和整体的关系,部分和整体的生命周期一致(比如说大雁和它的翅膀)
更改上面的代码:创建一个手机品牌抽象类和手机软件抽象类,让不同的品牌和功能都继承它们
桥接模式
public abstract class Software {
public abstract void run();
}
public abstract class Brand {
protected Software software;
//设置手机软件
public void setSoftware(Software software) {
this.software =software;
}
public abstract void run();
}
public class GameSoftware extends Software {
@Override
public void run() {
System.out.println("运行手机游戏");
}
}
public class AddressListSoftware extends Software{
@Override
public void run() {
System.out.println("运行通讯录功能");
}
}
public class MBrand extends Brand {
@Override
public void run() {
System.out.println("M品牌");
software.run();
}
}
public class NBrand extends Brand {
@Override
public void run() {
System.out.println("N品牌");
software.run();
}
}
public class Demo {
public static void main(String[]args) {
Brand br;
br=new MBrand();
br.setSoftware(new GameSoftware());
br.run();
br.setSoftware(new AddressListSoftware());
br.run();
br=new NBrand();
br.setSoftware(new GameSoftware());
br.run();
br.setSoftware(new AddressListSoftware());
br.run();
}
}
输出结果为:
M品牌
运行手机游戏
M品牌
运行通讯录功能
N品牌
运行手机游戏
N品牌
运行通讯录功能
手机品牌和软件是根据”一座桥”连接起来的,所以这个模式就叫做桥接模式
桥接模式:实现系统可能有多角度分类,每一种分类都可能有变化,那么就把这种多角度分离出来让它们独立变化(而如果使用继承会造成大量的类增加),减少它们之间的耦合.就刚才的例子而言,就是让”手机”可以按照品牌来分类,也可以按照功能来分类