C++设计模式4--桥接模式--处理多维度的需求变化

引言

桥接模式就将要解决什么样的问题呢?我们具几个显示中的例子来加深理解

例子一

    拿汽车在路上行驶的来说。即有轿车,又有公共汽车,它们都不但能在市区中的公路上行驶,也能在高速公路上行驶。这你会发现,对于不同的交通工具,行驶在不同的环境中,每个都作为一个需求,我们会有很多种可能的需求,

例子二

再比如说我们每天用的电脑,有各种牌子的,什么Dell,Hp,Acer,Lenovo,Apple,不同的电脑上还可以装不一样的操作系统,比如说Windows(WindowsXP,Windows7.Windows8),Linux(RedHat,Ubunto,LinuxMint,CentOS),MacOS等等,如果每台电脑配上一个操作系统,我么也会有很多的组合。

如果我们每个需求都用一个单独的类来对应,很容易出现问题,我们知道在继承的时候基类和子类的耦合度是很高的

传统方式的缺点

①首先它在遵循开放-封闭原则的同时,违背了类的单一职责原则,即一个类只有一个引起它变化的原因,而这里引起变化的原因却有两个,即电脑牌子的变化和操作系统类型的变化;

②其次是重复代码会很多,不同的电脑安装不同的操作系统也会有一部分的代码是相同的;

③再次是类的结构过于复杂,继承关系太多,难于维护,最后最致命的一点是扩展性太差。如果变化沿着电脑的牌子和不同的操作系统两个方向变化,我们会看到这个类的结构会迅速的变庞大。

小结

我们会发现,以前我们需求中的变动都是单维度的,也就是只有一个需求面在变动,而这次我们面临的时,几个不同的方向同时变动,每个变动,都会产生一个新的需求,我们需要去对应这些需求,以前那些模式都是不划算的,这时候桥接模式就出现了,用以应对这种多维度的需求变动

桥接模式概述

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

意图:

GOF在提出桥梁模式的时候指出,桥梁模式的用意是"将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化"。这句话有三个关键词,也就是抽象化、实现化和脱耦。

代码我们拿那个电脑上安装操作系统来讲解

首先看操作系统的代码

[cpp] view plain copy print?

  1. #ifndef __OS_H_INCLUDED__  
  2. #define __OS_H_INCLUDED__  
  3.   
  4.   
  5. // 操作系统  
  6. class OS  
  7. {  
  8. public :  
  9.     virtual ~OS( ){ };  
  10.     virtual void InstallOSImage( ) const = 0;          // 安装操作系统  
  11.   
  12. };  
  13.   
  14. // WINDOWS操作系统  
  15. class WindowsOS : public OS  
  16. {  
  17. public:  
  18.     virtual ~WindowsOS( ){  };  
  19.     void InstallOSImage( ) const  
  20.     {  
  21.         std::cout <<"安装WINDOWS操作系统" <<std::endl;  
  22.     }  
  23. };  
  24.   
  25. // LINUX操作系统  
  26. class LinuxOS : public OS  
  27. {  
  28. public:  
  29.     virtual ~LinuxOS( ){ };  
  30.     void InstallOSImage( ) const  
  31.     {  
  32.         std::cout <<"安装LINUX操作系统" <<std::endl;  
  33.     }  
  34. };  
  35.   
  36.   
  37. // MACOX操作系统  
  38. class MacOS : public OS  
  39. {  
  40. public:  
  41.     virtual ~MacOS( ){ };  
  42.     void InstallOSImage( ) const  
  43.     {  
  44.         std::cout <<"安装MACOS操作系统" <<std::endl;  
  45.     }  
  46. };  
  47.   
  48.   
  49.   
  50. #endif // __OS_H_INCLUDED__  
#ifndef __OS_H_INCLUDED__
#define __OS_H_INCLUDED__

// 操作系统
class OS
{
public :
    virtual ~OS( ){ };
    virtual void InstallOSImage( ) const = 0;          // 安装操作系统

};

// WINDOWS操作系统
class WindowsOS : public OS
{
public:
    virtual ~WindowsOS( ){  };
    void InstallOSImage( ) const
    {
        std::cout <<"安装WINDOWS操作系统" <<std::endl;
    }
};

// LINUX操作系统
class LinuxOS : public OS
{
public:
    virtual ~LinuxOS( ){ };
    void InstallOSImage( ) const
    {
        std::cout <<"安装LINUX操作系统" <<std::endl;
    }
};

// MACOX操作系统
class MacOS : public OS
{
public:
    virtual ~MacOS( ){ };
    void InstallOSImage( ) const
    {
        std::cout <<"安装MACOS操作系统" <<std::endl;
    }
};

#endif // __OS_H_INCLUDED__

下面看电脑的代码

在安装时候,传一个OS*类型的指针进来,从未指定安装某个操作系统

[cpp] view plain copy print?

  1. #ifndef __COMPUTER_H_INCLUDED__  
  2. #define __COMPUTER_H_INCLUDED__  
  3.   
  4. #include "OS.h"  
  5.   
  6. // 计算机的基类  
  7. class Computer  
  8. {  
  9. public :  
  10.     virtual ~Computer( ){ };  
  11.     virtual void InstallOS(const OS *os) = 0;          // 在计算机上安装操作系统  
  12.   
  13. };  
  14.   
  15. // 计算机的基类  
  16. class DellComputer : public Computer  
  17. {  
  18. public :  
  19.     virtual ~DellComputer( ){ };  
  20.     void InstallOS(const OS *os)          // 在计算机上安装操作系统  
  21.     {  
  22.         std::cout <<"我有台戴尔电脑..." <<std::endl;  
  23.         os->InstallOSImage( );                      // 安装操作系统的镜像  
  24.         std::cout <<std::endl;  
  25.     }  
  26. };  
  27.   
  28.   
  29.   
  30. // 计算机的基类  
  31. class AcerComputer : public Computer  
  32. {  
  33. public :  
  34.     virtual ~AcerComputer( ){ };  
  35.     void InstallOS(const OS *os)          // 在计算机上安装操作系统  
  36.     {  
  37.         std::cout <<"我有台宏基电脑..." <<std::endl;  
  38.         os->InstallOSImage( );                      // 安装操作系统的镜像  
  39.         std::cout <<std::endl;  
  40.     }  
  41.   
  42. };  
  43.   
  44. // 计算机的基类  
  45. class AppleComputer : public Computer  
  46. {  
  47. public :  
  48.     virtual ~AppleComputer( ){ };  
  49.     void InstallOS(const OS *os)          // 在计算机上安装操作系统  
  50.     {  
  51.         std::cout <<"我有台苹果电脑..." <<std::endl;  
  52.         os->InstallOSImage( );                      // 安装操作系统的镜像  
  53.         std::cout <<std::endl;  
  54.     }  
  55.   
  56. };  
  57. #endif // __COMPUTER_H_INCLUDED__  
#ifndef __COMPUTER_H_INCLUDED__
#define __COMPUTER_H_INCLUDED__

#include "OS.h"

// 计算机的基类
class Computer
{
public :
    virtual ~Computer( ){ };
    virtual void InstallOS(const OS *os) = 0;          // 在计算机上安装操作系统

};

// 计算机的基类
class DellComputer : public Computer
{
public :
    virtual ~DellComputer( ){ };
    void InstallOS(const OS *os)          // 在计算机上安装操作系统
    {
        std::cout <<"我有台戴尔电脑..." <<std::endl;
        os->InstallOSImage( );                      // 安装操作系统的镜像
        std::cout <<std::endl;
    }
};

// 计算机的基类
class AcerComputer : public Computer
{
public :
    virtual ~AcerComputer( ){ };
    void InstallOS(const OS *os)          // 在计算机上安装操作系统
    {
        std::cout <<"我有台宏基电脑..." <<std::endl;
        os->InstallOSImage( );                      // 安装操作系统的镜像
        std::cout <<std::endl;
    }

};

// 计算机的基类
class AppleComputer : public Computer
{
public :
    virtual ~AppleComputer( ){ };
    void InstallOS(const OS *os)          // 在计算机上安装操作系统
    {
        std::cout <<"我有台苹果电脑..." <<std::endl;
        os->InstallOSImage( );                      // 安装操作系统的镜像
        std::cout <<std::endl;
    }

};
#endif // __COMPUTER_H_INCLUDED__

下面看看主程序该怎么写

[cpp] view plain copy print?

  1. #include <iostream>  
  2.   
  3. #include "OS.h"  
  4. #include "Computer.h"  
  5.   
  6. using namespace std;  
  7.   
  8. int main()  
  9. {  
  10.     OS       *os = NULL;  
  11.     Computer *com = NULL;  
  12.   
  13.     os = new WindowsOS( );  
  14.     com = new DellComputer( );  
  15.     com->InstallOS(os);              // 在Dell笔记本上安装Windows操作系统  
  16.     delete os;  
  17.     os = NULL;  
  18.     delete com;  
  19.     com = NULL;  
  20.   
  21.     os = new LinuxOS( );  
  22.     com = new AcerComputer( );  
  23.     com->InstallOS(os);      // 在宏基电脑上安装Linux操作系统  
  24.     delete os;  
  25.     os = NULL;  
  26.     delete com;  
  27.     com = NULL;  
  28.   
  29.     os = new MacOS( );  
  30.     com = new AppleComputer( );  
  31.     com->InstallOS(os); // 在苹果机上安装MacOs  
  32.     delete os;  
  33.     os = NULL;  
  34.     delete com;  
  35.     com = NULL;  
  36.   
  37.     return 0;  
  38. }  
#include <iostream>

#include "OS.h"
#include "Computer.h"

using namespace std;

int main()
{
    OS       *os = NULL;
    Computer *com = NULL;

    os = new WindowsOS( );
    com = new DellComputer( );
    com->InstallOS(os);              // 在Dell笔记本上安装Windows操作系统
    delete os;
    os = NULL;
    delete com;
    com = NULL;

    os = new LinuxOS( );
    com = new AcerComputer( );
    com->InstallOS(os);      // 在宏基电脑上安装Linux操作系统
    delete os;
    os = NULL;
    delete com;
    com = NULL;

    os = new MacOS( );
    com = new AppleComputer( );
    com->InstallOS(os); // 在苹果机上安装MacOs
    delete os;
    os = NULL;
    delete com;
    com = NULL;

    return 0;
}

附言-另外的实现方式(组合/聚合)

另外还有一种是采用组合或者聚合的方式去实现代码部解释了直接附上

[cpp] view plain copy print?

  1. #include <iostream>  
  2.   
  3. //////////////////////////////////////////////////////////////////////////////////  
  4. // 操作系统  
  5. class OS  
  6. {  
  7. public :  
  8.     virtual ~OS( ){ };  
  9.     virtual void InstallOSImage( ) const = 0;          // 安装操作系统  
  10.   
  11. };  
  12.   
  13.   
  14. // WINDOWS操作系统  
  15. class WindowsOS : public OS  
  16. {  
  17. public:  
  18.     virtual ~WindowsOS( ){  };  
  19.     void InstallOSImage( ) const  
  20.     {  
  21.         std::cout <<"安装WINDOWS操作系统" <<std::endl;  
  22.     }  
  23. };  
  24.   
  25. // LINUX操作系统  
  26. class LinuxOS : public OS  
  27. {  
  28. public:  
  29.     virtual ~LinuxOS( ){ };  
  30.     void InstallOSImage( ) const  
  31.     {  
  32.         std::cout <<"安装LINUX操作系统" <<std::endl;  
  33.     }  
  34. };  
  35.   
  36.   
  37. // MACOX操作系统  
  38. class MacOS : public OS  
  39. {  
  40. public:  
  41.     virtual ~MacOS( ){ };  
  42.     void InstallOSImage( ) const  
  43.     {  
  44.         std::cout <<"安装MACOS操作系统" <<std::endl;  
  45.     }  
  46. };  
  47. //////////////////////////////////////////////////////////////////////////////////  
  48. //  
  49. //  
  50. //  
  51. //////////////////////////////////////////////////////////////////////////////////  
  52. // 计算机的基类  
  53. class Computer  
  54. {  
  55. public :  
  56.     Computer(OS *os)  
  57.     :m_os(os)  
  58.     {  
  59.     }  
  60.   
  61.     virtual ~Computer( )  
  62.     {  
  63.     };  
  64.     virtual void InstallOS( ) = 0;          // 在计算机上安装操作系统  
  65.   
  66. protected :  
  67.     OS  *m_os;                  // 安装的操作系统  
  68. };  
  69.   
  70. // 计算机的基类  
  71. class DellComputer : public Computer  
  72. {  
  73. public :  
  74.     DellComputer(OS *os)  
  75.     :Computer(os)  
  76.     {  
  77.     }  
  78.     virtual ~DellComputer( ){ };  
  79.     void InstallOS( )          // 在计算机上安装操作系统  
  80.     {  
  81.         std::cout <<"This is a DELL computer..." <<std::endl;  
  82.         this->m_os->InstallOSImage( );                      // 安装操作系统的镜像  
  83.         std::cout <<std::endl;  
  84.     }  
  85. };  
  86.   
  87.   
  88.   
  89. // 计算机的基类  
  90. class AcerComputer : public Computer  
  91. {  
  92. public :  
  93.     AcerComputer(OS *os)  
  94.     :Computer(os)  
  95.     {  
  96.     }  
  97.     virtual ~AcerComputer( )  
  98.     {  
  99.   
  100.     }  
  101.     void InstallOS( )          // 在计算机上安装操作系统  
  102.     {  
  103.         std::cout <<"This is a ACER computer..." <<std::endl;  
  104.         this->m_os->InstallOSImage( );                      // 安装操作系统的镜像  
  105.         std::cout <<std::endl;  
  106.     }  
  107.   
  108. };  
  109.   
  110. // 计算机的基类  
  111. class AppleComputer : public Computer  
  112. {  
  113. public :  
  114.     AppleComputer(OS *os)  
  115.     :Computer(os)  
  116.     {  
  117.     }  
  118.     virtual ~AppleComputer( ){ };  
  119.     void InstallOS( )          // 在计算机上安装操作系统  
  120.     {  
  121.         std::cout <<"This is a APPLE computer..." <<std::endl;  
  122.         this->m_os->InstallOSImage( );                      // 安装操作系统的镜像  
  123.         std::cout <<std::endl;  
  124.     }  
  125.   
  126. };  
  127. //////////////////////////////////////////////////////////////////////////////////  
  128. //  
  129. //  
  130. //  
  131. //  
  132. //////////////////////////////////////////////////////////////////////////////////  
  133. int main()  
  134. {  
  135.     OS       *os = NULL;  
  136.     Computer *com = NULL;  
  137.   
  138.     os = new WindowsOS( );  
  139.     com = new DellComputer(os);  
  140.     com->InstallOS( );// Dell上安装了Windows  
  141.     delete os;  
  142.     os = NULL;  
  143.     delete com;  
  144.     com = NULL;  
  145.   
  146.     os = new LinuxOS( );  
  147.     com = new AcerComputer(os);  
  148.     com->InstallOS( );// 宏基上装了个Linux  
  149.     delete os;  
  150.     os = NULL;  
  151.     delete com;  
  152.     com = NULL;  
  153.   
  154.     os = new MacOS( );  
  155.     com = new AppleComputer(os);  // 苹果电脑上安装MACOS  
  156.     com->InstallOS( );  
  157.     delete os;  
  158.     os = NULL;  
  159.     delete com;  
  160.     com = NULL;  
  161.   
  162.     return 0;  
  163. }  

转载:http://blog.csdn.net/gatieme/article/details/17994663

时间: 2024-10-31 22:35:05

C++设计模式4--桥接模式--处理多维度的需求变化的相关文章

C#设计模式(8)——桥接模式(Bridge Pattern)

原文:C#设计模式(8)--桥接模式(Bridge Pattern) 一.引言 这里以电视遥控器的一个例子来引出桥接模式解决的问题,首先,我们每个牌子的电视机都有一个遥控器,此时我们能想到的一个设计是--把遥控器做为一个抽象类,抽象类中提供遥控器的所有实现,其他具体电视品牌的遥控器都继承这个抽象类,具体设计类图如下: 这样的实现使得每部不同型号的电视都有自己遥控器实现,这样的设计对于电视机的改变可以很好地应对,只需要添加一个派生类就搞定了,但随着时间的推移,用户需要改变遥控器的功能,如:用户可能

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

原文:乐在其中设计模式(C#) - 桥接模式(Bridge Pattern)[索引页][源码下载] 乐在其中设计模式(C#) - 桥接模式(Bridge Pattern) 作者:webabcd 介绍 将抽象部分与它的实现部分分离,使它们都可以独立地变化. 示例 有一个Message实体类,对它的操作有Insert()和Get()方法,现在使这些操作的抽象部分和实现部分分离. MessageModel using System;using System.Collections.Generic;us

【设计模式】—— 桥接模式Bridge

模式意图 这个模式使用的并不多,但是思想确实很普遍.就是要分离抽象部分与实现部分. 实现弱关联,即在运行时才产生依赖关系. 降低代码之间的耦合. 模式结构 Abstraction 抽象部分的基类,定义抽象部分的基础内容. RefinedAbstraction 抽象部分的扩充,用于对基类的内容补充,添加特定场景的业务操作. Implementor 实现部分的基类,定义实现部分的基本内容. ConcreteImplementor 具体的实现类.   应用场景 1 不希望在抽象和它的实现部分之间有一个

设计模式:桥接模式(Bridge)

定义:将抽象部分与它的实现部分分离,使它们都可以独立地变化. 意图:将抽象与实现解耦.  桥接模式主要应对的是由于实际的需要,某个类具有两个或者两个以上的维度变化(违反了SRP原则),如果只是用继承将无法实现这种需要,或者使得设计变得相当臃肿. 桥接模式所涉及的角色 1. Abstraction:定义抽象接口,拥有一个Implementor类型的对象引用 2. RefinedAbstraction:扩展Abstraction中的接口定义 3. Implementor:是具体实现的接口,Imple

Head First设计模式之桥接模式

一.定义 桥接模式(Bridge Pattern),将抽象部分与它的实现部分分离,使的抽象和实现都可以独立地变化. 主要解决:在多维可能会变化的情况下,用继承会造成类爆炸问题,扩展起来不灵活. 何时使用:实现系统可能有多个角度分类,每一种角度都可能变化. 如何解决:把这种多角度分类分离出来,让它们独立变化,减少它们之间耦合. 注意事项:对于两个独立变化的维度,使用桥接模式再适合不过了. 二.结构   三.实现 一般写法 namespace DesignPatterns.Bridge { clas

C++设计模式之桥接模式_C 语言

问题描述 现在要去画一个图形,图形有长方形.圆形和扇形等等:而图形又可以加上不同的颜色,然后,我们就可以画出红色的长方形,绿色的长方形:红色的圆形,绿色的圆形等等.而这种图形的形状在变化,图形的颜色也在变化,当使用代码去实现时,如何面对这种多方面的变化呢?这就要说到今天的桥接模式了. 什么是桥接模式? 对于上述的图形与颜色的问题时,很多时候,我们让各个图形类继承颜色类,比如: 复制代码 代码如下: class CShape { }; class CRectangle : public CShap

php设计模式 Bridge (桥接模式)

复制代码 代码如下: <?php /** * 桥接模式 * * 将抽象部份与它实现部分分离,使用它们都可以有独立的变化 */ abstract class Implementor { abstract public function operation(); } class ConcreteImplementorA extends Implementor { public function operation() { echo "ConcreteImplementorA Operation

深入理解JavaScript系列(44):设计模式之桥接模式详解_基础知识

介绍 桥接模式(Bridge)将抽象部分与它的实现部分分离,使它们都可以独立地变化. 正文 桥接模式最常用在事件监控上,先看一段代码: 复制代码 代码如下: addEvent(element, 'click', getBeerById); function getBeerById(e) { var id = this.id; asyncRequest('GET', 'beer.uri?id=' + id, function(resp) { // Callback response. consol

温故而知新:设计模式之桥接模式(Bridge)

当一个应用,有着多个维度的变化时,桥模式可将多个维度的变化独立开来(即解耦),最直观的好处就是可有效减少子类的数量. 场景:假如我们要开发一个数据程序程序,导出的数据格式暂定为txt,xml,或直接导入到其它数据库(注:导出格式的需要变化,可以理解为功能维度上的变化),而且我们还要让这套程序能运行于多种平台(windows,linux,freebsd,macos...)上,即跨平台运行(注:可支持多平台的需要变化,可理解为平台需求维度上的变化) 如果按传统思维:每种格式的导出程序都要对应写出N个