首页 > 代码库 > Bridge桥接模式

Bridge桥接模式

当我们的功能要在多个维度进行扩展时,各个维度之间可以交叉组合,就可以考虑使用桥接模式。

将抽象部分与实现部分分离,使它们都可以独立的变化。
                                                                    ——《设计模式》GOF 

 

我们看一个实际的例子来理解:

我想发一条短信,首先,我要选择使用哪一种信号(联通、移动、电信);其次,我们要选择发送的内容(文本、附件、音频);最后,我们要选择发送的时间(实时、定时)。

那么,这里有三个维度的变化,每个维度有3、3、2种类型,如果我们使用传统的继承的方式来扩展一个类的功能,那么我们需要一个顶级短信发送类,3种信号类都去继承这个顶级类,3种内容类去继承每一种信号类,2种发送时间类再去继承每一种内容类。

这样我们得到了3*3*2+1=19个类(或者不要顶级类,得到18个类),如果再有其他的扩展维度进来的话,类的个数将不堪设想。

这时我们就可以考虑使用桥接模式,使各个扩展维度之间解耦,使它们相互独立。每个变化的维度都可以抽象成统一的类,由这个维度变化的子类去进行扩展。而各个维度的抽象类之间,可以相互持有各自的引用,从而拥有其他维度的功能。

 

各个变化维护的抽象类:

public abstract class Message {    private String content;    abstract public void send();        public String getContent() {        return content;    }    public void setContent(String content) {        this.content = content;    }}

 

public abstract class Signal {    protected Message msg;    public abstract void invoke();}

 

各个维度变化的子类:

public class TextMessage extends Message {    @Override    public void send() {        System.out.println("发送【文字】信息:" + this.getContent());    }}

 

public class PicMessage extends Message {    @Override    public void send() {        System.out.println("发送【图片】信息:" + this.getContent());    }}

 

public class AudioMessage extends Message {    @Override    public void send() {        System.out.println("发送【语音】信息:" + this.getContent());    }}

 

public class YiDongSignal extends Signal {    public YiDongSignal(Message msg) {        super();        this.msg = msg;    }    @Override    public void invoke() {        System.out.print("使用【移动】:");        msg.send();    }    }

 

public class LianTongSignal extends Signal {        public LianTongSignal(Message msg) {        super();        this.msg = msg;    }    @Override    public void invoke() {        System.out.print("使用【联通】:");        msg.send();    }    }

 

public class DianXinSignal extends Signal {    public DianXinSignal(Message msg) {        super();        this.msg = msg;    }    @Override    public void invoke() {        System.out.print("使用【电信】:");        msg.send();    }}

 

客户端调用:

public class Client {    public static void main(String[] args) {        Message msg = new TextMessage();        msg.setContent("Hello World!");        Signal signal = new YiDongSignal(msg);                signal.invoke();    }}

输出结果:

使用【移动】:发送【文字】信息:Hello World!

 

 

上面只扩展了两个维度,如果现在我们要扩展第三个维度--发送时间的话,就可以简单的加几个类就行了:

变化维度抽象类:

public abstract class SendTime {    protected Signal signal;    abstract public void sendMsg();}

变化维度子类:

public class InstantSendTime extends SendTime{        public InstantSendTime(Signal signal) {        super();        this.signal = signal;    }    @Override    public void sendMsg() {        System.out.print("【实时发送】-->");        this.signal.invoke();    }}

客户端调用:

public class Client2 {    public static void main(String[] args) {        Message msg = new TextMessage();        msg.setContent("Hello World!");        Signal signal = new YiDongSignal(msg);        SendTime sendTime = new InstantSendTime(signal);                sendTime.sendMsg();    }}

输出结果:

【实时发送】-->使用【移动】:发送【文字】信息:Hello World!

 

细心的读者不难发现,在我们客户端调用的时候,有点像Decorator装饰模式。

但它和Decorator是有区别的,Bridge是从多个维度扩展,而Decorator是将多个包装类的功能加在一起,组合成一个多功能的类。(描述不太清楚,后续修改)

Bridge桥接模式