桥接模式(Bridge Pattern)就是把事物和其具体实现分开,使他们可以各自独立的变化。桥接的用意是:将抽象化与实现化解耦,使得二者可以独立变化,像我们常用的JDBC桥DriverManager一样,JDBC进行连接数据库的时候,在各个数据库之间进行切换,基本不需要动太多的代码,甚至丝毫不用动,原因就是JDBC提供统一接口,每个数据库提供各自的实现,用一个叫做数据库驱动的程序来桥接就行了。桥接设计模式的类图如下所示:
定义一个抽象类Abstraction,持有Implementor接口。然后接口的具体实现类ConcreteImplementA和ConcreteImplementB具体实现。
下面我们假设实现一个简单的桥接设计模式案例。类图如下所示:
(1)定义Sourceable接口
为了命名规范,我们Sourceable接口写成ISourceable;
(2)实现ISourceable接口的实现类
(3)定义Bridge抽象类
(4)absBridge抽象类的具体实现类
(5)测试类
总结:
桥接设计模式其实摆脱了继承关系体系,通过多态的方式,具体的Bridge实现类中调用父类(抽象类)中的method方法,而该抽象类通过持有接口的引用,调用接口的method方法,而接口中的method方法由具体子类实现,因此传入什么实现类,就调用哪个实现类的method方法。
桥接设计模式的优点就是类间解耦,Sourceable接口的具体实现类也可以继续扩展下去。本例中的absBridge类似于JDBC中的DriverManager,Sourceable的具体实现类就类似于MySQL、ORACLE的驱动器。
思考1:谈到桥接模式,有必要说说类的继承有什么优缺点?
其实继承的优点有很多,可以把公共的方法或属性抽取,父类封装共性,子类实现特性,这是继承的基本功能。
那么继承的缺点有吗?有,强关联关系,父类有个方法,你子类也必须有这个方法,是不可选择的,那这会带来扩展性的问题,我举个简单的例子来说明这个问题:父(Father)类有一个方法A,子(Son)类继承了这个方法,然后子子(Grandson)类也继承了这个方法,问题是突然有一天子(Son)类要重写父类的这个方法,他敢做吗?绝对不敢!子子可是要用从父类(Father)继承过来的方法A,你修改了,那就要修改Son和GrandSon之间的关系,那这个风险就大了去。
今天讲的这个桥梁模式就是这一问题的解决方法,桥梁模式描述了类间弱关联关系,还说上面的那个例子,Fater类完全可以把可能会变化的方法放出去,Son子类要有这个方法很简答,桥梁搭过去,获得这个方法,GrandSon也一样,即使你Son子类不想使用这个方法了,也没关系,对GrandSon不产生影响,它不是从你Son中继承来的方法!