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

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

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

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

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

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

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

各个变化维护的抽象类:

  1. public abstract class Message {
  2. private String content;
  3. abstract public void send();
  4.  
  5. public String getContent() {
  6. return content;
  7. }
  8. public void setContent(String content) {
  9. this.content = content;
  10. }
  11. }
  1. public abstract class Signal {
  2. protected Message msg;
  3. public abstract void invoke();
  4. }

各个维度变化的子类:

  1. public class TextMessage extends Message {
  2.  
  3. @Override
  4. public void send() {
  5. System.out.println("发送【文字】信息:" + this.getContent());
  6. }
  7.  
  8. }
  1. public class PicMessage extends Message {
  2.  
  3. @Override
  4. public void send() {
  5. System.out.println("发送【图片】信息:" + this.getContent());
  6. }
  7.  
  8. }
  1. public class AudioMessage extends Message {
  2.  
  3. @Override
  4. public void send() {
  5. System.out.println("发送【语音】信息:" + this.getContent());
  6. }
  7.  
  8. }
  1. public class YiDongSignal extends Signal {
  2.  
  3. public YiDongSignal(Message msg) {
  4. super();
  5. this.msg = msg;
  6. }
  7.  
  8. @Override
  9. public void invoke() {
  10. System.out.print("使用【移动】:");
  11. msg.send();
  12. }
  13.  
  14. }
  1. public class LianTongSignal extends Signal {
  2.  
  3. public LianTongSignal(Message msg) {
  4. super();
  5. this.msg = msg;
  6. }
  7.  
  8. @Override
  9. public void invoke() {
  10. System.out.print("使用【联通】:");
  11. msg.send();
  12. }
  13.  
  14. }
  1. public class DianXinSignal extends Signal {
  2.  
  3. public DianXinSignal(Message msg) {
  4. super();
  5. this.msg = msg;
  6. }
  7.  
  8. @Override
  9. public void invoke() {
  10. System.out.print("使用【电信】:");
  11. msg.send();
  12. }
  13. }

客户端调用:

  1. public class Client {
  2. public static void main(String[] args) {
  3. Message msg = new TextMessage();
  4. msg.setContent("Hello World!");
  5. Signal signal = new YiDongSignal(msg);
  6.  
  7. signal.invoke();
  8. }
  9. }

输出结果:

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

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

变化维度抽象类:

  1. public abstract class SendTime {
  2. protected Signal signal;
  3. abstract public void sendMsg();
  4. }

变化维度子类:

  1. public class InstantSendTime extends SendTime{
  2.  
  3. public InstantSendTime(Signal signal) {
  4. super();
  5. this.signal = signal;
  6. }
  7.  
  8. @Override
  9. public void sendMsg() {
  10. System.out.print("【实时发送】-->");
  11. this.signal.invoke();
  12. }
  13. }

客户端调用:

  1. public class Client2 {
  2. public static void main(String[] args) {
  3. Message msg = new TextMessage();
  4. msg.setContent("Hello World!");
  5. Signal signal = new YiDongSignal(msg);
  6. SendTime sendTime = new InstantSendTime(signal);
  7.  
  8. sendTime.sendMsg();
  9. }
  10. }

输出结果:

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

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

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

可以再看看Decorator装饰模式自己体味区别

Bridge桥接模式的更多相关文章

  1. C++设计模式-Bridge桥接模式

    作用:将抽象部份与它的实现部份分离,使它们都可以独立地变化. 将抽象(Abstraction)与实现(Implementation)分离,使得二者可以独立地变化. 桥接模式号称设计模式中最难理解的模式 ...

  2. Bridge桥接模式(结构型模式)

    现有一个需求,一个游戏系统需要构建不同风格的房屋,暂不考虑其他设计模式,需要能实现在PC端.移动端....等等多个平台的构建.最简单的实现方式如下: /// <summary> /// 房 ...

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

    Bridge 桥接模式(结构型模式) 抽象与实现 抽象不应该依赖于实现细节,实现细节应该依赖于抽象. 抽象B稳定,实现细节b变化 问题在于如果抽象B由于固有的原因,本身并不稳定,也有可能变化,怎么办? ...

  4. Bridge桥接模式(设计模式11)

    在没有使用桥接模式: 扩展新问题(类归属膨胀问题) 1增加性的电脑类型,要增加每个品牌下面的类 2如果要增加一个新的电脑品牌,要增加美中电脑类型的类 违背单一职责原则: · 一个类:联想笔记本,有两个 ...

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

    一.概念准备 在理解桥接模式之前,先要理解面向对象程序设计中的两个概念: 类的功能层次结构:假设现在有一个类Something,这个类有一些成员属性和成员方法,但是现有的功能不能满足要求,因此我们想扩 ...

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

    1. 概述 在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?如何利用面向对象的技术来使得该类型能够轻松的沿着多个方向进行变化,而又不引入额外的复杂度 ...

  7. 面向对象设计模式纵横谈:Bridge 桥接模式(笔记记录)

    桥接模式是一个比较难理解的设计模式,设计和分析的时候也不容易把握,咱们听听“李建忠”老师是怎么来讲的.我们还是从演变的角度来说问题,一步一步的来把问题说清楚.先谈谈“抽象”和“实现”的关系. 抽象与实 ...

  8. Bridge 桥接模式 MD

    桥接模式 简介 将抽象部分与实现部分分离,使它们都可以独立的变化. 业务抽象角色引用业务实现角色,或者说业务抽象角色的部分实现是由业务实现角色完成的 Bridge模式基于类的最小设计原则,通过使用封装 ...

  9. Bridge - 桥接模式

    1. 概述 在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?如何利用面向对象的技术来使得该类型能够轻松的沿着多个方向进行变化,而又不引入额外的复杂度 ...

随机推荐

  1. Goal driven performance optimization

    When your goal is to optimize application performance it is very important to understand what goal d ...

  2. linux服务之audit

    http://blog.chinaunix.net/uid-20786165-id-3167391.html http://blog.chinaunix.net/uid-8389195-id-1741 ...

  3. linux服务之asterisk

    由于Asterisk过于专业且复杂,所以目前也存在大量衍生自Asterisk但简化过的通信系统,以让用户较容易使用.比如在欧美比较流行的elastix.trixbox.或以简体中文为基础的Freeir ...

  4. Android Afinal框架

    项目如图: 本文参考网络! Afinal是一个开源的android的orm和ioc应用开发框架,其特点是小巧灵活,代码入侵量少.在android应用开发中,通过 Afinal的ioc框架,诸如ui绑定 ...

  5. HTML5之Canvas绘图——使用Canvas绘制图形的基本教程

    原文转自:http://www.cnblogs.com/picaso/archive/2012/11/26/2789077.html HTML5火的正热,最近有个想法也是要用到HTML的相关功能,所以 ...

  6. Mock框架

    MoQ(基于.net3.5,c#3.0的mock框架)简单介绍 - 你听海是不是在笑 - 博客园 http://www.cnblogs.com/nuaalfm/archive/2009/11/25/1 ...

  7. phpcmsv9如何实现添加栏目时不在首页内容区显示只在导航栏显示

    之前王晟璟一直使用PHPCMSV9系统建过自己的个人门户网站,同时也建立了一个其他类型的网站,感觉非常不错,我不得不说PHPCMSV9的功能非常齐全,非常强大. 但有一点时常让王晟璟感到很烦脑,那就是 ...

  8. html中间块居中宽度自适应

    说来,这个其实不是个多难的事情,但是,若没有经验或者没有了解过html原数在浏览器中显示的顺序,可能还真是个问题,不知如何调整. 先说明下,在确定了左右两边显示的块的宽度后,再让中间块的宽度自适应,这 ...

  9. 十个 MongoDB 使用要点

    转自: 十个 MongoDB 使用要点    从 mongodb 阶段性技术总结 中抽取并整理了对大家有帮助的十个要点:   1.mongodb 表名和字段名统一用小写字母 mongodb 是默认区分 ...

  10. IntelliJ IDEA常用快捷键

    双击shift 项目所有目录查找 ctrl+f 文件查找特定内容 ctrl+shift+f 项目查找包含特定内容的文件 ctrl+n 新建类 ctrl+shift+n 查找文件 ctrl+e  最近的 ...