桥接模式(Bridge)
首先分享关于桥接模式的一遍好文章; 研磨设计模式之桥接模式 https://www.oschina.net/question/1435262_140274
桥接模式的定义是:将抽象部分和它的实现部分分离,使他们都可以独立的变化;关系如下图:

Abstraction:
抽象部分的接口。通常在这个对象里面,要维护一个实现部分的对象引用,在抽象对象里面的方法,需要调用实现部分的对象来完成。这个对象里面的方法,通常都是跟具体的业务相关的方法。
RefinedAbstraction:
扩展抽象部分的接口,通常在这些对象里面,定义跟实际业务相关的方法,这些方法的实现通常会使用Abstraction中定义的方法,也可能需要调用实现部分的对象来完成。
Implementor:
定义实现部分的接口,这个接口不用和Abstraction里面的方法一致,通常是由Implementor接口提供基本的操作,而Abstraction里面定义的是基于这些基本操作的业务方法,也就是说Abstraction定义了基于这些基本操作的较高层次的操作。
ConcreteImplementor:
真正实现Implementor接口的对象。
是不是看的一脸懵逼,不急,我们举个例子来分析一下:
做我们这行的应该都玩过英雄联盟;游戏中地图分几种模式(如:大乱斗、匹配、排位);而且每种模式每个人都可以成一百多个英雄种选取一个,我们改如何应对这种多对多的关系呢?
按照以前的法我们肯定会采用继承,如下图:

代码如下:
//地图接口 public interface Ditu { public void run(); } //大乱斗地图 public class DaLuandouDitu implements Ditu{ public void run() { System.out.println("大乱斗地图"); } } //匹配模式地图 public class PipeiDitu implements Ditu{ public void run() { System.out.println("匹配模式地图"); } } /德码 类 public class Dama extends DaLuandouDitu{ public void run(){ System.out.println("德码在大乱斗地图"); } } public class Dema2 extends PipeiDitu{ public void run(){ System.out.println("德码在匹配地图"); } }
//寒冰省略
这种写法不仅代码混乱,关系复杂,重复的也多;而且扩展性也差;假设现在我要增一个英雄和一个模式,简直是一个噩梦;
我们用桥接模式来做:首先将抽象部分和它的实现部分分离;如下图:

代码如下:
实现部分
//英雄接口 public interface XYinterface { public void run(); } //英雄 德码 类 public class Dama implements XYinterface{ public void run(){ System.out.println("大宝剑德码"); } } //英雄寒冰 public class HanBing implements XYinterface{ public void run(){ System.out.println("百步穿杨小寒冰"); } }
抽象部分:
//抽象部分 public abstract class AbstractDitu { protected XYinterface xYinterface; public abstract void getDitu(); public XYinterface getxYinterface() { return xYinterface; } public void setxYinterface(XYinterface xYinterface) { this.xYinterface = xYinterface; } } //大乱斗地图 public class DaLuandouDitu extends AbstractDitu{ @Override public void getDitu() { xYinterface.run(); System.out.println("在大乱斗地图"); } } //匹配模式地图 public class PipeiDitu extends AbstractDitu{ @Override public void getDitu() { xYinterface.run(); System.out.println("在大乱斗地图"); } }
测试如下:
public class Test { public static void main(String[] args) { XYinterface xYinterface=new HanBing(); AbstractDitu ab=new PipeiDitu(); ab.setxYinterface(xYinterface); ab.getDitu(); } }
输出
百步穿杨小寒冰
在匹配地图
在这种模式下新增一种模式或一种英雄就很简单了;只要实现相对的抽象接口即可;
认识桥接模式(来自分享博客)
(1)什么是桥接
在桥接模式里面,不太好理解的就是桥接的概念,什么是桥接?为何需要桥接?如何桥接?把这些问题搞清楚了,也就基本明白桥接的含义了。
一个一个来,先看什么是桥接?所谓桥接,通俗点说就是在不同的东西之间搭一个桥,让他们能够连接起来,可以相互通讯和使用。那么在桥接模式中到底是给什么东西来搭桥呢?就是为被分离了的抽象部分和实现部分来搭桥,比如前面示例中抽象的消息和具体消息发送之间搭个桥。
但是这里要注意一个问题:在桥接模式中的桥接是单向的,也就是只能是抽象部分的对象去使用具体实现部分的对象,而不能反过来,也就是个单向桥。
(2)为何需要桥接
为了达到让抽象部分和实现部分都可以独立变化的目的,在桥接模式中,是把抽象部分和实现部分分离开来的,虽然从程序结构上是分开了,但是在抽象部分实现的时候,还是需要使用具体的实现的,这可怎么办呢?抽象部分如何才能调用到具体实现部分的功能呢?很简单,搭个桥不就可以了,搭个桥,让抽象部分通过这个桥就可以调用到实现部分的功能了,因此需要桥接。
(3)如何桥接
这个理解上也很简单,只要让抽象部分拥有实现部分的接口对象,这就桥接上了,在抽象部分就可以通过这个接口来调用具体实现部分的功能。也就是说,桥接在程序上就体现成了在抽象部分拥有实现部分的接口对象,维护桥接就是维护这个关系。
(4)独立变化
桥接模式的意图:使得抽象和实现可以独立变化,都可以分别扩充。也就是说抽象部分和实现部分是一种非常松散的关系,从某个角度来讲,抽象部分和实现部分是可以完全分开的,独立的,抽象部分不过是一个使用实现部分对外接口的程序罢了。
如果这么看桥接模式的话,就类似于策略模式了,抽象部分需要根据某个策略,来选择真实的实现,也就是说桥接模式的抽象部分相当于策略模式的上下文。更原始的就直接类似于面向接口编程,通过接口分离的两个部分而已。但是别忘了,桥接模式的抽象部分,是可以继续扩展和变化的,而策略模式只有上下文,是不存在所谓抽象部分的。
那抽象和实现为何还要组合在一起呢?原因是在抽象部分和实现部分还是存在内部联系的,抽象部分的实现通常是需要调用实现部分的功能来实现的。
浙公网安备 33010602011771号