设计模式之桥接模式
定义
桥接模式是将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。 —— [ 百度百科 ]
解释说明
在桥接模式中,分为实现方和抽象方。实现方中,我们定义一个接口,子类继承这个接口,具备了相同的实现方行为。在抽象方中,定义一个抽象类,类中内置实现方接口类型的一个实例,同时再定义抽象的表现方法。子类继承抽象类,可以重新定义表现方法。
代码块
public class Test {
//实现方角色
interface KungFu{
public void say();
}
//具体实现A
class KungFuA implements KungFu{
@Override
public void say() {
System.out.println("我会降龙十八掌");
}
}
//具体实现B
class KungFuB implements KungFu{
@Override
public void say() {
System.out.println("我会葵花宝典");
}
}
//抽象方父类
abstract class Man{
public Man(KungFu kungFu){
this.kungFu = kungFu;
}
public void showKungFu(){
kungFu.say();
}
private KungFu kungFu;
}
//抽象方实现类A
class ManA extends Man{
public ManA(KungFu kungFu){
super(kungFu);
}
public void say(){
System.out.println("我是乔峰");
super.showKungFu();
}
}
//抽象方实现类B
class ManB extends Man{
public ManB(KungFu kungFu){
super(kungFu);
}
public void say(){
System.out.println("我是东方不败");
super.showKungFu();
}
}
//测试
public static void main(String[] args) {
//乔峰实现
KungFu kungFuA = new Test().new KungFuA();
ManA manA = new Test().new ManA(kungFuA);
manA.say();
//东方不败实现
KungFu kungFuB = new Test().new KungFuB();
ManB manB = new Test().new ManB(kungFuB);
manB.say();
}
}
: 以上就是桥接模式的完整代码。男人和功夫之间我们不去构造继承这种强关联关系,而是采用组合这种弱的关联关系,实现了两者之间的解耦。在上述例子中,我们首先对功夫的实现,定义统一的接口(KungFu),然后由不同的功夫类(KungFuA,KungFuB)去实现不同的功能。其次,我们对男人抽象出Man类,并在其中内置了一个KungFu类型的成员变量,当子类(ManA,ManB)继承抽象类的时候,同时继承了抽象类中对功夫这一行为的表现形式。在不同的子类中,我们不仅可以自由的组合不同的功夫行为,同时也可在其中添加自己的业务逻辑,丰富这一行为
总结
以下总结是基于这种模式本身固有的特性展开了叙述,重复理解其特点,就是明白了这种模式的优点。
优点
- 抽象化
存在于多个实体中的共同的概念性联系,就是抽象化。作为一个过程,抽象化就是忽略一些信息,从而把不同的实体当做同样的实体对待 - 实现化
抽象化给出的具体实现,就是实现化。 - 脱耦
所谓耦合,就是两个实体的行为的某种强关联。而将它们的强关联去掉,就是耦合的解脱,或称脱耦。在这里,脱耦是指将抽象化和实现化之间的耦合解脱开,或者说是将它们之间的强关联改换成弱关联。
将两个角色之间的继承关系改为聚合关系,就是将它们之间的强关联改换成为弱关联。因此,桥梁模式中的所谓脱耦,就是指在一个软件系统的抽象化和实现化之间使用组合/聚合关系而不是继承关系,从而使两者可以相对独立地变化。这就是桥梁模式的用意。
缺点
- 过度的设计必将会导致代码的复杂度增加,同时桥接模式的运用基于自身对抽象概念的深刻理解熟练运用的基础上。
试用场景
如果一个系统需要在抽象化和具体化之间增加更多的灵活性,避免在多个层次之间建立静态的继承关系,通过桥接模式可以使它们在抽象层建立一个关联关系。
“抽象部分”和“实现部分”可以以继承的方式独立扩展而互不影响,在程序运行时可以动态将一个抽象化子类的对象和一个实现化子类的对象进行组合,即系统需要对抽象化角色和实现化角色进行动态耦合。
一个类存在两个(或多个)独立变化的维度,且这两个(或多个)维度都需要独立进行扩展。
对于那些不希望使用继承或因为多层继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。