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是将多个包装类的功能加在一起,组合成一个多功能的类。(描述不太清楚,后续修改)

时间: 2024-11-06 14:31:48

Bridge桥接模式的相关文章

设计模式(八):Bridge桥接模式 -- 结构型模式

1. 概述 在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?如何利用面向对象的技术来使得该类型能够轻松的沿着多个方向进行变化,而又不引入额外的复杂度? 例子1:设想如果要绘制矩形.圆形.椭圆.正方形,我们至少需要4个形状类,但是如果绘制的图形需要具有不同的颜色,如红色.绿色.蓝色等,此时至少有如下两种设计方案: •第一种设计方案是为每一种形状都提供一套各种颜色的版本. •第二种设计方案是根据实际需要对形状和颜色进行组合. 方案1: 方案2:  

Bridge(桥接)模式

Bridge(桥接)模式用于将抽象与抽象的实现分离,使它们可以独自变化. 适用于以下几种情况: 不希望在抽象和它的实现部分之间有一个固定的绑定关系,例如这种情况可能是因为,在程序运行时刻实现部分应可以被选择或者切换. 类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充.这时Bridge模式使你可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充. 对一个抽象的实现部分的修改应对客户不产生影响,即客户的代码不必重新编译. 想在多个对象间共享实现(可能使用引用计数),但同时要求客户并不

设计模式07: Bridge 桥接模式(结构型模式)

Bridge 桥接模式(结构型模式) 抽象与实现 抽象不应该依赖于实现细节,实现细节应该依赖于抽象. 抽象B稳定,实现细节b变化 问题在于如果抽象B由于固有的原因,本身并不稳定,也有可能变化,怎么办? 举例来说 假如我们需要开发一个同时支持PC和手机的坦克游戏,游戏在PC和手机上功能都一样,都有同样的类型,面临同样的需求变化,比如坦克可能有多种不同的型号:T50,T75,T90…… 对于其中坦克设计,我们可能很容易设计出来一个Tank的抽象基类: /// <summary> /// 抽象Tan

一天一个设计模式——Bridge桥接模式

一.概念准备 在理解桥接模式之前,先要理解面向对象程序设计中的两个概念: 类的功能层次结构:假设现在有一个类Something,这个类有一些成员属性和成员方法,但是现有的功能不能满足要求,因此我们想扩展这个类,给这个类创建一个子类SomethingBetter来继承它,并在子类中添加更多属性和方法.像这样不同的功能位于不同的类继承结构中,就构成了类的功能层次结构. 类的实现层次结构:回顾一下抽象类的作用,抽象类声明抽象方法(定义了方法接口API),然后在继承它的子类中实现相关方法.由于我们将方法

设计模式(7)--Bridge(桥接模式)--结构型

1.模式定义: 桥接模式是对象的结构模式.又称为柄体(Handle and Body)模式或接口(Interface)模式.桥接模式的用意是“将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化”. 2.模式特点: 桥接模式虽然不是一个使用频率很高的模式,但是熟悉这个模式对于理解面向对象的设计原则,包括“开-闭”原则以及组合/聚合复用原则都很有帮助.理解好这两个原则,有助于形成正确的设计思想和培养良好的设计风格. 桥接模式的用意是“将抽象化(Ab

设计模式的征途—8.桥接(Bridge)模式

在现实生活中,我们常常会用到两种或多种类型的笔,比如毛笔和蜡笔.假设我们需要大.中.小三种类型的画笔来绘制12中不同的颜色,如果我们使用蜡笔,需要准备3*12=36支.但如果使用毛笔的话,只需要提供3种型号的毛笔,外加12个颜料盒即可,涉及的对象个数仅为3+12=15,远远小于36却能实现与36支蜡笔同样的功能.如果需要新增一种画笔,并且同样需要12种颜色,那么蜡笔需要增加12支,而毛笔却只需要新增1支.通过分析,在蜡笔中,颜色和型号两个不同的变化维度耦合在一起,无论对其中任何一个维度进行扩展,

NET设计模式 第二部分 结构性模式(8):桥接模式(Bridge Pattern)

桥接模式(Bridge Pattern) ——.NET设计模式系列之九 Terrylee,2006年2月 概述 在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?如何利用面向对象的技术来使得该类型能够轻松的沿着多个方向进行变化,而又不引入额外的复杂度?这就要使用Bridge模式. 意图 将抽象部分与实现部分分离,使它们都可以独立的变化.[GOF <设计模式>] 结构图 图1 Bridge模式结构图 生活中的例子 桥接模式将抽象部分与它的实现分离

.NET设计模式(9):桥接模式(Bridge Pattern)(转)

概述 在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?如何利用面向对象的技术来使得该类型能够轻松的沿着多个方向进行变化,而又不引入额外的复杂度?这就要使用Bridge模式. 意图 将抽象部分与实现部分分离,使它们都可以独立的变化.[GOF <设计模式>] 结构图 图1 Bridge模式结构图 生活中的例子 桥接模式将抽象部分与它的实现分离,使它们能够独立地变化.一个普通的开关控制的电灯.电风扇等等,都是桥接的例子.开关的目的是将设备打开或关闭

如何使用桥接模式使虚拟机VMware中的Redhat能上网

VMware中有三种网络连接方式可使其上网:桥接模式,NAT模式,host-only模式,下面详细介绍如何使用桥接模式使虚拟机中的Redhat连上互联网. Bridge(桥接)模式 在Bridge模式下,虚拟机VMware虚拟出来的系统就像是局域网中一台独立的主机.使用这种模式时,虚拟机中的Redhat的必须设置为跟主机在同一个网段下. 这种模式下,默认使用VMnet0 将虚拟机中Redhat的ip设置为与主机同网段未使用的ip,其余与主机相同.例如:主机的ip地址为192.168.1.102,