在现实生活中,我们常常会用到两种或多种类型的笔,比如毛笔和蜡笔。假设我们需要大、中、小三种类型的画笔来绘制12中不同的颜色,如果我们使用蜡笔,需要准备3*12=36支。但如果使用毛笔的话,只需要提供3种型号的毛笔,外加12个颜料盒即可,涉及的对象个数仅为3+12=15,远远小于36却能实现与36支蜡笔同样的功能。如果需要新增一种画笔,并且同样需要12种颜色,那么蜡笔需要增加12支,而毛笔却只需要新增1支。通过分析,在蜡笔中,颜色和型号两个不同的变化维度耦合在一起,无论对其中任何一个维度进行扩展,都势必会影响另外一个维度。但在毛笔中,颜色和型号实现了分离,增加新的颜色或者型号都对另外一方没有任何影响。在软件系统中,有些类型由于自身的逻辑,它具有两个或多个维度的变化。为了解决这种多维度变化,又不引入复杂度,这就要使用今天介绍的Bridge桥接模式。

一、跨平台的图像浏览系统

1.1 需求介绍

M公司开发部想要开发一个跨平台的图像浏览系统,要求该系统能够显示JPG、BMP、GIF、PNG等多种格式的文件,并且能够在Windows、Linux以及Unix等多个操作系统上运行。该系统首先将各种格式的文件解析为像素矩阵(Matrix),然后将像素矩阵显示在屏幕上,在不同的操作系统中可以调用不同的绘制函数来绘制像素矩阵。该系统需要具备较好的扩展性以支持新的文件格式和操作系统。

1.2 初始设计

  M公司开发部的程序猿针对需求,立马提出了一个初始的设计方案,其基本结构如下图所示:

  通过对这个设计方案的分析,发现存在以下两个主要问题:

  (1)由于采用了多重继承结构,导致系统中类的个数急剧增加,系统中类的个数达到了17个。

  (2)系统扩展麻烦,由于每一个具体类既包括图像文件格式信息,又包含操作系统信息,因此无论增加新图像文件格式还是新的操作系统,都需要增加大量的具体类。这将导致系统变得非常庞大,增加运行和维护开销。

1.3 多维度变化

  通过分析可以知道,这个系统存在两个独立变化的维度:图像文件格式和操作系统,如下图所示:

  如何将各种不同类型的图像文件解析为像素矩阵与图像文件格式本身相关,而如何在屏幕上绘制像素矩阵又与操作系统相关。因为初始设计中将这两种职责集中在一个类中,导致系统扩展麻烦,从类的设计角度分析,具体类BMPWindowsImage、BMPLinuxImage、BMPUnixImage等类违反了单一职责原则,因为有不止一个引起它们变化的原因,将图像文件解析和像素矩阵显示这两种完全不同的职责耦合在一起,任意一个职责发生变化都需要修改它们,因此系统扩展十分麻烦。

二、桥接模式简介

2.1 模式概述

  桥接模式是一种很实用的结构型模式,如果软件系统中某个类存在两个独立变化的维度,通过该模式可以将这两个维度分离出来,使两者可以独立扩展,让系统更加符合单一职责原则。桥接模式主要使用抽象关联取代传统的多重继承,将类之间的静态继承关系转换为动态地对象组合关系,使得系统更加灵活,并易于扩展,同时有效地控制了系统中类的个数

  桥接模式的定义如下:

桥接(Bridge)模式:将抽象部分与其实现部分分离,使得他们都可以独立地变化。它是一种对象结构型模式,又称为接口模式。

2.2 类图

  

2.3 代码实现

  图像抽象类和实例类

#pragma once
#include <string>
#include <iostream>
using namespace std; class CAbstractPicture
{
public:
CAbstractPicture(){}
~CAbstractPicture(){} virtual void Convert() = ;
}; class CBmp : public CAbstractPicture
{
public:
CBmp(string strFileName):m_strFileName(strFileName)
{
cout << "CBmp Construct" << endl;
} ~CBmp()
{
cout << "CBmp Deconstruct" << endl;
} void Convert()
{
cout << "图片格式为bmp" <<endl;
} private:
string m_strFileName;
}; class CJpg : public CAbstractPicture
{
public:
CJpg(string strFileName):m_strFileName(strFileName)
{
cout << "CJpg Construct" << endl;
} ~CJpg()
{
cout << "CJpg Deconstruct" << endl;
} void Convert()
{
cout << "图片格式为jpg" <<endl;
} private:
string m_strFileName;
}; class Cpng : public CAbstractPicture
{
public:
Cpng(string strFileName):m_strFileName(strFileName)
{
cout << "Cpng Construct" << endl;
} ~Cpng()
{
cout << "Cpng Deconstruct" << endl;
} void Convert()
{
cout << "图片格式为png" <<endl;
} private:
string m_strFileName;
};

  操作系统抽象类和实例类

#pragma once

#include "IntfPicture.h"

class CAbstractOs
{
public:
CAbstractOs(){}
~CAbstractOs(){} virtual void ShowPicture(CAbstractPicture *pPicture) = ;
}; class CWindows : public CAbstractOs
{
public:
CWindows()
{
cout << "CWindows Construct" << endl;
}
~CWindows()
{
cout << "CWindows Deconstruct" << endl;
} void ShowPicture(CAbstractPicture *pPicture)
{
cout << "在windwos中显示图像"<< endl;
pPicture->Convert();
}
}; class CLinux : public CAbstractOs
{
public:
CLinux()
{
cout << "CLinux Construct" << endl;
}
~CLinux()
{
cout << "CLinux Deconstruct" << endl;
} void ShowPicture(CAbstractPicture *pPicture)
{
cout << "在windwos中显示图像"<< endl;
pPicture->Convert();
}
};

  测试代码

#include "stdio.h"

#include "IntfOs.h"

void main()
{
CAbstractOs *pOs = new CWindows();
CAbstractPicture *pPicture = new CBmp("xxx.bmp");
pOs->ShowPicture(pPicture);
pPicture = new CJpg("xxx.jpg");
pOs->ShowPicture(pPicture); delete pPicture;
delete pOs;
return;
}

三、桥接模式小结

3.1 主要优点

  (1)分离抽象接口及其实现部分 -> 桥接模式使用“对象间的关联关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度变化

  (2)取代多层继承方案 -> 极大地减少了子类的个数

  (3)提高了系统可扩展性 -> 在两个变化维度中任意扩展一个维度,都不需要修改原有系统,符合开闭原则

3.2 主要缺点

  (1)增加了系统的理解和设计难度 -> 需要开发者在一开始就对抽象层进行设计与编程

  (2)要求正确识别出系统中两个独立变化的维度 -> 如何正确地识别需要一定的经验积累

3.3 应用场景

  (1)一个类存在两个(或者多个)独立变化的维度,而且这两个(或者多个)维度都需要独立进行扩展。

  (2)不希望使用继承或因为多层继承而导致系统中类的个数急剧增加。

  (3)一个系统需要在抽象类和具体类之间增加更多的灵活性,避免在两个层次之间建立静态继承关系,通过桥接可以使它们在抽象层建立一个关联关系。

注:参考博客http://www.cnblogs.com/edisonchou/p/6978351.html

设计模式之桥接(bridge)模式的更多相关文章

  1. 设计模式初探-桥接(Bridge)模式

    桥接(Bridge)模式,又称Handle/Body模式,属于对象结构型模式.用于将抽象部分与它的实现部分分离,使它们都可以独立地变化.比如常见的电脑窗口界面,不同的操作系统其窗口界面绘制的原理肯定不 ...

  2. Java 实现桥接(Bridge)模式

    类图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamp3d21scDQ1Ng==/font/5a6L5L2T/fontsize/400/fill/I0 ...

  3. 设计模式C++描述----09.桥接(Bridge)模式

    一. 举例 N年前: 计算机最先出来时,软件和硬件是一绑在一起的,比如IBM出了一台电脑,上面有一个定制的系统,假如叫 IBM_Win,这个IBM_Win系统当然不能在HP电脑上运行,同样HP出的HP ...

  4. Java设计模式---桥接Bridge模式

    参考于 : 大话设计模式 马士兵设计模式视频 写在开头: 桥接模式主要用于一件事物分成了两个维度,进行排列组合,比如礼物,可以分成优雅的礼物(抽象),花(具体),排列组合优雅的花! 1.为什么使用桥接 ...

  5. 设计模式--桥接(Bridge)模式

    1.概述: 桥接模式:把抽象和行为分离开来,中间需要某个介质来连接抽象化和行为化.此模式的概述听起来非常像适配器模式,不要搞混了,虽然都是借用中间介质,但意义不同.最典型的桥接模式就是:JDBC.通过 ...

  6. 漫谈设计模式(三):桥接(Bridge)模式 —— 将类功能、结构两层次分离

    1.前言 类主要有两个层次,一个是功能层次,另一个是实现层次. 功能层次,一般应用于当前类不能满足多样化的业务需求,让子类去继承(具体)父类,添加加一些父类中没有的功能(一般是增加新的方法),这就属于 ...

  7. 桥接(Bridge)模式

    桥接模式又称为柄体模式或接口模式.桥接模式的用意就是"将抽象化与实现化解耦,使得二者可以独立变化". 抽象化: 存在于多个实体中的共同的概念性联系,就是抽象化.作为一个过程,抽象化 ...

  8. [设计模式] 7 桥接模式 bridge

    #include<iostream> using namespace std; class AbstractionImp { public: virtual ~AbstractionImp ...

  9. 乐在其中设计模式(C#) - 桥接模式(Bridge Pattern)

    原文:乐在其中设计模式(C#) - 桥接模式(Bridge Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 桥接模式(Bridge Pattern) 作者:webabcd 介绍 ...

  10. 【设计模式】Bridge模式(桥接模式)

    最近的一次面试中,被问到桥接模式,以前呢并没有很仔细的研究过这个设计模式,借此机会剖析一下. 先给出自己对这个模式理解后的源码: interface A{ void methodA(); } inte ...

随机推荐

  1. CSS3:布局display属性的flex(弹性布局)

    CSS3:布局display属性的flex(弹性布局) 一.简介 Flex是Flexible Box的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性.设为Flex布局以后, ...

  2. Apache 域名跳转配置

    域名跳转 就是实现URL的跳转和隐藏真实地址,基于Perl语言的正则表达式规范.平时帮助我们实现拟静态,拟目录,域名跳转,防止盗链等 .   参数格式 参数: Apache mod_rewrite 规 ...

  3. Windows 10 安装 到SSD硬盘

    1.更换SSD硬盘 2.安装windows 10 系统(升级太慢,建议全新安装) 3.全程不到1个小时个月安装完成. 4.这个分数惨不忍睹,但是速度还是蛮快. 5.挂载机械硬盘,安装驱动,window ...

  4. CSS3 3D旋转动画菜单

    在线演示 本地下载

  5. SQL注入导图

    本图来自信安之路学生渗透小组@辽宁-web-TwoDog, 博主觉得这张图画的很好,所以贴在这里提供参考!

  6. 20145201 《Java程序设计》第五周学习总结

    20145201 <Java程序设计>第五周学习总结 教材学习内容总结 本周学习了课本第八.九章内容,即异常处理.Collection与Map. 第八章 异常处理 8.1 语法与集成架构 ...

  7. Oracle大总结

    maven的常见两个指令说明 mvn install 是将你打好的jar包安装到你的本地库中,一般没有设置过是在 用户目录下的 .m2\下面.mvn package 只是将你的代码打包到输出目录,一般 ...

  8. v4l2 下载

    To clone the master development repository, install git, and run: git clone git://github.com/torvald ...

  9. python数据可视化(持续更新)

    1.折线图 import numpy as np import matplotlib.pyplot as plt input_values = [1, 2, 3, 4, 5] s = [1, 4, 9 ...

  10. LeetCode——single-number系列

    LeetCode--single-number系列 Question 1 Given an array of integers, every element appears twice except ...