• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > C++设计模式编程中使用Bridge桥接模式的完全攻略

C++设计模式编程中使用Bridge桥接模式的完全攻略

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了c++设计模式,c++设计模式pdf,c++设计模式视频教程,c++设计模式视频,c++设计模式面试题等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

桥接模式将抽象(Abstraction)与实现(Implementation)分离,使得二者可以独立地变化。

桥接模式典型的结构图为:

201631395440751.jpg (557×221)

在桥接模式的结构图中可以看到,系统被分为两个相对独立的部分,左边是抽象部分,右边是实现部分,这两个部分可以互相独立地进行修改:例如上面问题中的客户需求变化,当用户需求需要从 Abstraction 派生一个具体子类时候,并不需要像上面通过继承方式实现时候需要添加子类 A1 和 A2 了。另外当上面问题中由于算法添加也只用改变右边实现(添加一个具体化子类),而右边不用在变化,也不用添加具体子类了。

一切都变得 elegant!

桥接模式号称设计模式中最难理解的模式之一,关键就是这个抽象和实现的分离非常让人奇怪,大部分人刚看到这个定义的时候都会认为实现就是继承自抽象,那怎么可能将他们分离呢。

《大话设计模式》中就Bridge模式的解释:

手机品牌和软件是两个概念,不同的软件可以在不同的手机上,不同的手机可以有相同的软件,两者都具有很大的变动性。如果我们单独以手机品牌或手机软件为基类来进行继承扩展的话,无疑会使类的数目剧增并且耦合性很高,(如果更改品牌或增加软件都会增加很多的变动)两种方式的结构如下:

201631395516057.png (552×343)

201631395538456.jpg (572×317)

所以将两者抽象出来两个基类分别是PhoneBrand和PhoneSoft,那么在品牌类中聚合一个软件对象的基类将解决软件和手机扩展混乱的问题,这样两者的扩展就相对灵活,剪短了两者的必要联系,结构图如下:

201631395621451.png (590×245)

这样扩展品牌和软件就相对灵活独立,达到解耦的目的!

抽象基类及接口:

1、Abstraction::Operation():定义要实现的操作接口

2、AbstractionImplement::Operation():实现抽象类Abstaction所定义操作的接口,由其具体派生类ConcreteImplemenA、ConcreteImplemenA或者其他派生类实现。

3、在Abstraction::Operation()中根据不同的指针多态调用AbstractionImplement::Operation()函数。

理解:
Bridge用于将表示和实现解耦,两者可以独立的变化.在Abstraction类中维护一个AbstractionImplement类指针,需要采用不同的实现方式的时候只需要传入不同的AbstractionImplement派生类就可以了.

Bridge的实现方式其实和Builde十分的相近,可以这么说:本质上是一样的,只是封装的东西不一样罢了.两者的实现都有如下的共同点:

抽象出来一个基类,这个基类里面定义了共有的一些行为,形成接口函数(对接口编程而不是对实现编程),这个接口函数在Buildier中是BuildePart函数在Bridge中是Operation函数;

其次,聚合一个基类的指针,如Builder模式中Director类聚合了一个Builder基类的指针,而Brige模式中Abstraction类聚合了一个AbstractionImplement基类的指针(优先采用聚合而不是继承);

而在使用的时候,都把对这个类的使用封装在一个函数中,在Bridge中是封装在Director::Construct函数中,因为装配不同部分的过程是一致的,而在Bridge模式中则是封装在Abstraction::Operation函数中,在这个函数中调用对应的AbstractionImplement::Operation函数.就两个模式而言,Builder封装了不同的生成组成部分的方式,而Bridge封装了不同的实现方式.

桥接模式就将实现与抽象分离开来,使得RefinedAbstraction依赖于抽象的实现,这样实现了依赖倒转原则,而不管左边的抽象如何变化,只要实现方法不变,右边的具体实现就不需要修改,而右边的具体实现方法发生变化,只要接口不变,左边的抽象也不需要修改。


优点
1.将实现抽离出来,再实现抽象,使得对象的具体实现依赖于抽象,满足了依赖倒转原则。

2.将可以共享的变化部分,抽离出来,减少了代码的重复信息。

3.对象的具体实现可以更加灵活,可以满足多个因素变化的要求。

缺点
客户必须知道选择哪一种类型的实现。
设计中有超过一维的变化我们就可以用桥模式。如果只有一维在变化,那么我们用继承就可以圆满的解决问题。

代码示例:

Abstraction.h

#ifndef _ABSTRACTION_H_
#define _ABSTRACTION_H_

class AbstractionImplement;

class Abstraction
{
public:
  virtual void Operation()=0;//定义接口,表示该类所支持的操作
  virtual ~Abstraction();
protected:
  Abstraction();
};

class RefinedAbstractionA:public Abstraction
{
public:
  RefinedAbstractionA(AbstractionImplement* imp);//构造函数
  virtual void Operation();//实现接口
  virtual ~RefinedAbstractionA();//析构函数
private:
  AbstractionImplement* _imp;//私有成员
};

class RefinedAbstractionB:public Abstraction
{
public:
  RefinedAbstractionB(AbstractionImplement* imp);//构造函数
  virtual void Operation();//实现接口
  virtual ~RefinedAbstractionB();//析构函数
private:
  AbstractionImplement* _imp;//私有成员
};
#endif

Abstraction.cpp
#include "Abstraction.h"
#include "AbstractionImplement.h"
#include <iostream>

using namespace std;

Abstraction::Abstraction()
{}

Abstraction::~Abstraction()
{}

RefinedAbstractionA::RefinedAbstractionA(AbstractionImplement* imp)
{
  this->_imp = imp;
}

RefinedAbstractionA::~RefinedAbstractionA()
{
  delete this->_imp;
  this->_imp = NULL;
}

void RefinedAbstractionA::Operation()
{
  cout << "RefinedAbstractionA::Operation" << endl;
  this->_imp->Operation();
}

RefinedAbstractionB::RefinedAbstractionB(AbstractionImplement* imp)
{
  this->_imp = imp;
}

RefinedAbstractionB::~RefinedAbstractionB()
{
  delete this->_imp;
  this->_imp = NULL;
}

void RefinedAbstractionB::Operation()
{
  cout << "RefinedAbstractionB::Operation" << endl;
  this->_imp->Operation();
}

AbstractImplement.h
#ifndef _ABSTRACTIONIMPLEMENT_H_
#define _ABSTRACTIONIMPLEMENT_H_

//抽象基类,定义了实现的接口
class AbstractionImplement
{
public:
  virtual void Operation()=0;//定义操作接口
  virtual ~AbstractionImplement();
protected:
  AbstractionImplement();
};

// 继承自AbstractionImplement,是AbstractionImplement的不同实现之一
class ConcreteAbstractionImplementA:public AbstractionImplement
{
public:
  ConcreteAbstractionImplementA();
  void Operation();//实现操作
  ~ConcreteAbstractionImplementA();
protected:
};

// 继承自AbstractionImplement,是AbstractionImplement的不同实现之一
class ConcreteAbstractionImplementB:public AbstractionImplement
{
public:
  ConcreteAbstractionImplementB();
  void Operation();//实现操作
  ~ConcreteAbstractionImplementB();
protected:
};
#endif

AbstractImplement.cpp
#include "AbstractionImplement.h"
#include <iostream>

using namespace std;

AbstractionImplement::AbstractionImplement()
{}

AbstractionImplement::~AbstractionImplement()
{}

ConcreteAbstractionImplementA::ConcreteAbstractionImplementA()
{}

ConcreteAbstractionImplementA::~ConcreteAbstractionImplementA()
{}

void ConcreteAbstractionImplementA::Operation()
{
  cout << "ConcreteAbstractionImplementA Operation" << endl;
}

ConcreteAbstractionImplementB::ConcreteAbstractionImplementB()
{}

ConcreteAbstractionImplementB::~ConcreteAbstractionImplementB()
{}

void ConcreteAbstractionImplementB::Operation()
{
  cout << "ConcreteAbstractionImplementB Operation" << endl;
}

</div>

main.cpp

#include "Abstraction.h"
#include "AbstractionImplement.h"
#include <iostream>

using namespace std;

int main()
{
  /* 将抽象部分与它的实现部分分离,使得它们可以独立地变化

  1、抽象Abstraction与实现AbstractionImplement分离;

  2、抽象部分Abstraction可以变化,如new RefinedAbstractionA(imp)、new RefinedAbstractionB(imp2);

  3、实现部分AbstractionImplement也可以变化,如new ConcreteAbstractionImplementA()、new ConcreteAbstractionImplementB();

  */

  AbstractionImplement* imp = new ConcreteAbstractionImplementA();    //实现部分ConcreteAbstractionImplementA
  Abstraction* abs = new RefinedAbstractionA(imp);            //抽象部分RefinedAbstractionA
  abs->Ope



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 深入理解C++之策略模式
  • C++设计模式之工厂模式
  • C++设计模式编程中简单工厂与工厂方法模式的实例对比
  • 详解C++设计模式编程中对访问者模式的运用
  • 深入解析C++设计模式编程中解释器模式的运用
  • C++设计模式编程之Flyweight享元模式结构详解
  • 详解C++设计模式编程中责任链模式的应用
  • C++设计模式编程中使用Bridge桥接模式的完全攻略
  • C++设计模式编程中的迭代器模式应用解析
  • 深入剖析设计模式中的组合模式应用及在C++中的实现

相关文章

  • 2017-05-28C语言实现BMP转换JPG的方法
  • 2017-05-28深入解读C语言中的符号常量EOF
  • 2017-05-28C++实现单链表删除倒数第k个节点的方法
  • 2017-05-28基于C语言实现五子棋游戏完整实例代码
  • 2017-05-28提高C程序效率的10种有效方法
  • 2017-05-28使用C语言求二叉树结点的最低公共祖先的方法
  • 2017-05-28如何用C语言去除字符串两边的空字符
  • 2017-05-28浅谈c++中的输入输出方法
  • 2017-05-28贪吃蛇游戏C++命令行版实例代码
  • 2017-05-28C语言获取消耗内存的方法

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • YUV格式与RGB格式的相互转换公式及C++代码
    • C++中一维数组与指针的关系详细总结
    • 深入解读C++中的指针变量
    • 交换两个文本内容的C语言代码
    • C++实现查找中位数的O(N)算法和Kmin算法
    • C语言实现返回字符串函数的四种方法
    • 解析c++中的默认operator=操作的详解
    • C语言中操作密码文件的一些函数总结
    • 从汇编看c++函数的默认参数的使用说明
    • 算法之排列算法与组合算法详解

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有