一、基本介绍
桥接模式(结构型):将实现和抽象放在两个不同的类层次,使两个层次都可以独立的变化。
二、包含角色
1.抽象化角色:抽象化角色,包含对实现化抽象的引用。
2.拓展抽象化角色:抽象化角色的子类,实现父类中的业务方法,并调用其它具体实现化角色。
3.实现化角色:定义实现化角色的接口,供扩展抽象化角色调用。
4.具体实现化角色:给出实现化角色接口的具体实现。
三、案例及UML类图
案例说明:
如今的智能手表还处于发展阶段,智能手表的功能也比较单一,以后极大可能会拓展其功能,且在日后也 会有更多的公司加入智能手表的制造中。如果使用单一的继承来实现此需求,则设计一个智能手表抽象类, 每个公司都继承该类,每个公司都有各自不同的功能,当市场上新增一个公司时,都需要重新写每个方法,当智能手表功能新增时,每个公司都需要新增一个方法。此不符合单一职责原则,且也不易维护,当公司变多, 或功能变多时,需要修改极多的类,会产生类爆炸问题 桥接模式通过把两个变化因素抽象隔离开来,当功能拓展时也不必去修改公司的变化, 当公司变化时,也不必去修改功能的变化。例如:当智能手机的公司增加时,只需要去继承SmartWatchAbstraction,当功能增加时, 也只需要去实现FunctionImplementor接口即可。
UML类图:
类FunctionImplementor:
public interface FunctionImplementor {
/**
* 调用某功能
*/
void invoke();
}
说明:智能手表功能定义接口,实现化角色,定义功能的公共接口,智能手表新增功能可通过实现该接口进行拓展。
类CallFunction:
public class CallFunction implements FunctionImplementor {
@Override
public void invoke() {
System.out.println("调用智能手表打电话功能!");
}
}
说明:智能手表打电话的功能,具体实现化角色,拓展出智能手表的打电话功能。
类InternetFunction:
public class InternetFunction implements FunctionImplementor {
@Override
public void invoke() {
System.out.println("调用智能手表上网功能!");
}
}
说明:智能手表上网的功能,具体实现化角色,拓展出智能手表的上网功能。
类SmartWatchAbstraction:
public abstract class SmartWatchAbstraction {
protected FunctionImplementor functionImplementor;
public SmartWatchAbstraction(FunctionImplementor functionImplementor) {
this.functionImplementor = functionImplementor;
}
public abstract void invoke();
}
说明:智能手表抽象类,抽象化角色,定义智能手表的属性和方法,当需要拓展厂商时,可继承该类进行拓展。
类AppleSmartWatch:
public class AppleSmartWatch extends SmartWatchAbstraction {
public AppleSmartWatch(FunctionImplementor functionImplementor) {
super(functionImplementor);
}
@Override
public void invoke() {
System.out.println("加载ios系统");
functionImplementor.invoke();
}
}
说明:苹果手表厂商,拓展抽象化角色,定义苹果厂商的智能手表。
类XiaoMiSmartWatch:
public class XiaoMiSmartWatch extends SmartWatchAbstraction {
public XiaoMiSmartWatch(FunctionImplementor functionImplementor) {
super(functionImplementor);
}
@Override
public void invoke() {
System.out.println("加载安卓系统!");
functionImplementor.invoke();
}
}
说明:小米手表厂商,拓展抽象化角色,定义小米厂商的智能手表。
类BridgeTest:
public class BridgeTest {
public static void main(String[] args) {
//使用小米手表的打电话功能
SmartWatchAbstraction smartWatch = new XiaoMiSmartWatch(new CallFunction());
smartWatch.invoke();
//再使用苹果手表的打电话功能
smartWatch = new AppleSmartWatch(new CallFunction());
smartWatch.invoke();
//使用小米手表的上网功能
smartWatch = new XiaoMiSmartWatch(new InternetFunction());
smartWatch.invoke();
//再使用苹果手表的上网功能
smartWatch = new AppleSmartWatch(new InternetFunction());
smartWatch.invoke();
}
}
说明:测试及客户端类,通过对拓展抽象化角色和具体实现化角色的不同组合,能得到不同厂商有不同功能的效果,并且厂商和功能都是可拓展的。
四、适用场景
1.当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时。
2.当一个系统不希望使用继承或因为多层次继承导致系统类的个数急剧增加时,即需要避免类爆炸问题时。