当前位置: 首页 > 编程日记 > 正文

设计模式之桥接模式(Bridge)摘录

23种GOF设计模式一般分为三大类:创建型模式、结构型模式、行为模式。

创建型模式包括:1、FactoryMethod(工厂方法模式);2、Abstract Factory(抽象工厂模式);3、Singleton(单例模式);4、Builder(建造者模式、生成器模式);5、Prototype(原型模式).

结构型模式包括:6、Bridge(桥接模式);7、Adapter(适配器模式);8、Decorator(装饰模式);9、Composite(组合模式);10、Flyweight(享元模式);11、Facade(外观模式);12、Proxy(代理模式).

行为模式包括:13、TemplateMethod(模板方法模式);14、Strategy(策略模式);15、State(状态模式);16、Observer(观察者模式);17、Memento(备忘录模式);18、Mediator(中介者模式);19、Command(命令模式);20、Visitor(访问者模式);21、Chain of Responsibility(责任链模式);22、Iterator(迭代器模式);23、Interpreter(解释器模式).

Factory Method:定义一个用于创建对象的接口,让子类决定将哪一个类实例化。Factory Method使一个类的实例化延迟到其子类。

Abstract Factory:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。

Singleton:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

Builder:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

Prototype:用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象。

Bridge:将抽象部分与它的实现部分分离,使它们都可以独立地变化。

Adapter:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

Decorator:动态地给一个对象添加一些额外的职责。就扩展功能而言, Decorator模式比生成子类方式更为灵活。

Composite:将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得客户对单个对象和复合对象的使用具有一致性。

Flyweight:运用共享技术有效地支持大量细粒度的对象。

Facade:为子系统中的一组接口提供一个一致的界面, Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

Proxy:为其他对象提供一个代理以控制对这个对象的访问。

Template Method:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

Strategy:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。本模式使得算法的变化可独立于使用它的客户。

State:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它所属的类。

Observer:定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新。

Memento:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到保存的状态。

Mediator:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

Command:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可取消的操作。

Visitor:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

Chain of Responsibility:为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它。

Iterator:提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。

Interpreter:给定一个语言, 定义它的文法的一种表示,并定义一个解释器, 该解释器使用该表示来解释语言中的句子。

Bridge:(1)、意图:将抽象部分与它的实现部分分离,使它们都可以独立地变化。

(2)、适用性:A、你不希望在抽象和它的实现部分之间有一个固定的绑定关系。例如这种情况可能是因为,在程序运行时刻实现部分应可以被选择或者切换;B、类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。这时Bridge模式使你可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充;C、对一个抽象的实现部分的修改应对客户不产生影响,即客户的代码不必重新编译;D、(C++)你想对客户完全隐藏抽象的实现部分。在C++中,类的表示在类接口中是可见的;E、你想在多个对象间共享实现(可能使用引用计数),但同时要求客户并不知道这一点。

(3)、优点:A、分离接口及其实现部分:一个实现未必不变地绑定在一个接口上。抽象类的实现可以在运行时刻进行配置,一个对象甚至可以在运行时刻改变它的实现。将Abstraction与Implementor分离有助于降低对实现部分编译时刻的依赖性,当改变一个实现类时,并不需要重新编译Abstraction类和它的客户程序。为了保证一个类库的不同版本之间的二进制兼容性,一定要有这个性质。另外,接口与实现分离有助于分层,从而产生更好的结构化系统,系统的高层部分仅需知道Abstraction和Implementor即可。B、提高可扩充性:你可以独立地对Abstraction和Implementor层次结构进行扩充。C、实现细节对客户透明:你可以对客户隐藏实现细节,例如共享Implementor对象以及相应的引用计数机制(如果有的话)。

(4)、注意事项:A、仅有一个Implementor:在仅有一个实现的时候,没有必要创建一个抽象的Implementor类。这是Bridge模式的退化情况,在Abstraction和Implementor之间有一种一对一的关系。尽管如此,当你希望改变一个类的实现不会影响已有的客户程序时,模式的分离机制还是非常有用的----也就是说,不必重新编译它们,仅需重新连接即可。B、创建正确的Implementor对象:当存在多个Implementor类的时候,你应该用何种方法,在何时何处确定创建哪一个Implementor类呢?如果Abstraction知道所有的ConcreteImplementor类,它就可以在它的构造器中对其中的一个类进行实例化,它可以通过传递给构造器的参数确定实例化哪一个类。例如,如果一个collection类支持多重实现,就可以根据collection的大小决定实例化哪一个类。链表的实现可以用于较小的collection类,而hash表则可用于较大的collection类。另外一种方法是首先选择一个缺省的实现,然后根据需要改变这个实现。例如,如果一个collection的大小超出了一定的阈值时,它将会切换它的实现,使之更适合用于表目较多的collection.也可以代理给另一个对象,由它一次决定。C、共享Implementor对象。D、采用多重继承机制:在C++中可以使用多重继承机制将抽象接口和它的实现部分结合起来。例如,一个类可以用public方式继承Abstraction而以private方式继承ConcreteImplementor。但是由于这种方式依赖于静态继承,它将实现部分与接口固定不变的绑定在一起。因此不可能使用多重继承的方法实现真正的Bridge模式----至少用C++不行。

(5)、Abstract Factory模式可以用来创建和配置一个特定的Bridge模式。Adapter模式用来帮助无关的类协同工作,它通常在系统设计完成后才会被使用。然而,Bridge模式则是在系统开始时就被使用,它使得抽象接口和实现部分可以独立进行改变。

Bridge将抽象部分与实现部分分离,使它们可以独立变化。这里说的意思不是让抽象基类与具体类分离,而是现实系统可能有多角度分类,每一种分类都有可能变化,那么把这种多角度分离出来让它们独立变化,减少它们之间的耦合性,即如果继承不能实现”开放----封闭原则”的话,就应该考虑用桥接模式。

GoF在说明Bridge模式时,在意图中指出Bridge模式“将抽象部分与它的实现部分分离,使得它们可以独立地变化”。这句话很简单,但是也很复杂。原因就在于GoF的那句话中的“实现”该怎么去理解:“实现”特别是和“抽象”放在一起的时候我们“默认”的理解是“实现”就是“抽象”的具体子类的实现,但是这里GoF所谓的“实现”的含义不是指抽象基类的具体子类对抽象基类中虚函数(接口)的实现,是和继承结合在一起的。而这里的“实现”的含义指的是怎么去实现用户的需求,并且指的是通过组合(委托)的方式实现的,因此这里的实现不是指的继承基类、实现基类接口,而是指的是通过对象组合实现用户的需求。

示例代码1:

#include <iostream>
#include <string>
#include <vector>
using namespace std;//手机软件
class HandsetSoft
{
public:virtual void Run() = 0;
};//游戏软件
class HandsetGame : public HandsetSoft
{
public:virtual void Run(){cout<<"运行手机游戏"<<endl;}
};//通讯录软件
class HandSetAddressList : public HandsetSoft
{
public:virtual void Run(){cout<<"手机通讯录"<<endl;}
};//手机品牌
class HandsetBrand
{
protected:HandsetSoft* m_soft;
public:void SetHandsetSoft(HandsetSoft* temp){m_soft = temp;}virtual void Run() = 0;
};//M品牌
class HandsetBrandM : public HandsetBrand
{
public:virtual void Run(){m_soft->Run();}
};//N品牌
class HandsetBrandN : public HandsetBrand
{
public:virtual void Run(){m_soft->Run();}
};//客户端
int main()
{HandsetBrand* brand;brand = new HandsetBrandM();brand->SetHandsetSoft(new HandsetGame());brand->Run();brand->SetHandsetSoft(new HandSetAddressList());brand->Run();/* result:运行手机游戏手机通讯录*/return 0;
}

示例代码2:

abstraction.h:

#ifndef _ABSTRACTION_H_
#define _ABSTRACTION_H_class AbstractionImp;class Abstraction
{
public:virtual ~Abstraction();virtual void Operation() = 0;
protected:Abstraction();
private:
};class RefinedAbstraction : public Abstraction
{
public:RefinedAbstraction(AbstractionImp* imp);~RefinedAbstraction();void Operation();
protected:
private:AbstractionImp* _imp;
};#endif//_ABSTRACTION_H_

abstraction.cpp:

#include "abstraction.h"
#include "abstractionImp.h"#include <iostream>
using namespace std;Abstraction::Abstraction()
{}Abstraction::~Abstraction()
{}RefinedAbstraction::RefinedAbstraction(AbstractionImp* imp)
{_imp = imp;
}RefinedAbstraction::~RefinedAbstraction()
{}void RefinedAbstraction::Operation()
{_imp->Operation();
}

abstractionImp.h:

#ifndef _ABSTRACTIONIMP_H_
#define _ABSTRACTIONIMP_H_class AbstractionImp
{
public:virtual ~AbstractionImp();virtual void Operation() = 0;
protected:AbstractionImp();
private:
};class ConcreteAbstractionImpA : public AbstractionImp
{
public:ConcreteAbstractionImpA();~ConcreteAbstractionImpA();virtual void Operation();
protected:
private:
};class ConcreteAbstractionImpB : public AbstractionImp
{
public:ConcreteAbstractionImpB();~ConcreteAbstractionImpB();virtual void Operation();
protected:
private:
};#endif //_ABSTRACTIONIMP_H_

abstractionImp.cpp:

#include "abstractionImp.h"
#include <iostream>
using namespace std;AbstractionImp::AbstractionImp()
{}AbstractionImp::~AbstractionImp()
{}void AbstractionImp::Operation()
{cout<<"AbstractionImp .... imp ..."<<endl;
}ConcreteAbstractionImpA::ConcreteAbstractionImpA()
{}ConcreteAbstractionImpA::~ConcreteAbstractionImpA()
{}void ConcreteAbstractionImpA::Operation()
{cout<<"ConcreteAbstractionImpA ...."<<endl;
}ConcreteAbstractionImpB::ConcreteAbstractionImpB()
{}ConcreteAbstractionImpB::~ConcreteAbstractionImpB()
{}void ConcreteAbstractionImpB::Operation()
{cout<<"ConcreteAbstractionImpB ...."<<endl;
}

main.cpp:

#include "abstraction.h"
#include "abstractionImp.h"#include <iostream>
using namespace std;int main()
{AbstractionImp* imp = new ConcreteAbstractionImpA();Abstraction* abs = new RefinedAbstraction(imp);abs->Operation();/* result:ConcreteAbstractionImpA ....*/return 0;
}

桥接模式结构图:


参考文献:

1、《大话设计模式C++》

2、《设计模式精解----GoF23种设计模式解析》

3、《设计模式----可复用面向对象软件的基础》


相关文章:

原360首席科学家颜水成正式加入依图科技,任首席技术官

7 月 29 日&#xff0c;依图科技宣布原 360 首席科学家颜水成正式加入&#xff0c;担任依图科技首席技术官&#xff08;CTO&#xff09;一职。依图方面称&#xff0c;颜水成加入后将带领团队进一步夯实依图在人工智能基础理论和原创算法方面的技术优势&#xff0c;为依图在商业…

分布式存储fastdfs安装使用

1.下载地址https://github.com/happyfish100/fastdfshttps://github.com/happyfish100/fastdfs/wiki安装辅助说明文档2.安装编译环境yum install git gcc gcc-c make automake autoconf libtool pcre pcre-devel zlib zlib-devel openssl-devel wget vim -y三台主机&#xff1a…

Hibernate学习(九)———— 二级缓存和事务级别详讲

序言 这算是hibernate的最后一篇文章了&#xff0c;下一系列会讲解Struts2的东西&#xff0c;然后说完Struts2&#xff0c;在到Spring&#xff0c;然后在写一个SSH如何整合的案例。之后就会在去讲SSM&#xff0c;在之后我自己的个人博客应该也差不多可以做出来了。基本上先这样…

超详细中文预训练模型ERNIE使用指南

作者 | 高开远&#xff0c;上海交通大学&#xff0c;自然语言处理研究方向最近在工作上处理的都是中文语料&#xff0c;也尝试了一些最近放出来的预训练模型&#xff08;ERNIE&#xff0c;BERT-CHINESE&#xff0c;WWM-BERT-CHINESE&#xff09;&#xff0c;比对之后还是觉得百…

linux内核SMP负载均衡浅析

需求 在《linux进程调度浅析》一文中提到&#xff0c;在SMP&#xff08;对称多处理器&#xff09;环境下&#xff0c;每个CPU对应一个run_queue&#xff08;可执行队列&#xff09;。如果一个进程处于TASK_RUNNING状态&#xff08;可执行状态&#xff09;&#xff0c;则它…

结构体中最后一个成员为[0]或[1]长度数组(柔性数组成员)的用法

结构体中最后一个成员为[0]长度数组的用法&#xff1a;这是个广泛使用的常见技巧&#xff0c;常用来构成缓冲区。比起指针&#xff0c;用空数组有这样的优势&#xff1a;(1)、不需要初始化&#xff0c;数组名直接就是所在的偏移&#xff1b;(2)、不占任何空间&#xff0c;指针需…

超全!深度学习在计算机视觉领域的应用一览

作者 | 黄浴&#xff0c;奇点汽车美研中心首席科学家兼总裁转载自知乎简单回顾的话&#xff0c;2006年Geoffrey Hinton的论文点燃了“这把火”&#xff0c;现在已经有不少人开始泼“冷水”了&#xff0c;主要是AI泡沫太大&#xff0c;而且深度学习不是包治百病的药方。计算机视…

SHAREPOINT2010数据库升级2013

在作TEST-SPCONTENT命令时&#xff0c;会提示认证方式不一样。 The [SharePoint - 80] web application is configured with claims authentication mode however the content database you are trying to attach is intended to be used against a windows classic authentic…

设计模式之简单工厂模式(Simply Factory)摘录

从设计模式的类型上来说&#xff0c;简单工厂模式是属于创建型模式&#xff0c;又叫静态工厂方法(Static Factory Method)模式&#xff0c;但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的…

别得意,你只是假装收藏了而已

今天分享我在看罗振宇的《2018 时间的朋友》演讲视频记下的一些思考。跨年演讲中有过这样的一个来自印象笔记的片段&#xff0c;列举了几组对比来说明&#xff1a; 『你在朋友圈里又佛又丧&#xff0c;你在收藏夹里偷偷地积极向上。』 扎心了&#xff0c;这不就是说我吗&#x…

Exchange2003-2010迁移系列之四,配置第一台Exchange CAS/HUB服务器

配置第一台CAS/HUB关于Cas/hub的配置请大家详见前面关于Ex2010的部署&#xff08;两个配置基本相同在这里就不做详细的解说了&#xff09;下面关于Cas的配置在前面已经提到了但是下面是另一种新的方法大家就看看吧生产环境中部署Exchange2010服务器时&#xff0c;是需要按照一定…

设计模式之适配器模式(Adapter)摘录

23种GOF设计模式一般分为三大类&#xff1a;创建型模式、结构型模式、行为模式。 创建型模式抽象了实例化过程&#xff0c;它们帮助一个系统独立于如何创建、组合和表示它的那些对象。一个类创建型模式使用继承改变被实例化的类&#xff0c;而一个对象创建型模式将实例化委托给…

JAVA方法中的参数用final来修饰的效果

很多人都说在JAVA中用final来修饰方法参数的原因是防止方法参数在调用时被篡改&#xff0c;其实也就是这个原因&#xff0c;但理解起来可能会有歧义&#xff0c;我们需要注意的是&#xff0c;在final修饰的方法参数中&#xff0c;如果修饰的是基本类型&#xff0c;那么在这个方…

2019世界机器人大赛圆满落幕,荆州中学等15支队伍获「全能奖」

7月28日&#xff0c;2019世界机器人大赛总决赛在河北保定圆满落下帷幕。保定市市委常委罗德强、中国电子学会副秘书长梁靓、保定市政府秘书长王保辉、保定市政府副秘书长安利文、保定市徐水区区长李志永、保定市莲池区政府党组副书记赵建军、世界机器人大赛组委会秘书长李洋、长…

在任何设备上都完美呈现的30个华丽的响应式网站

如今&#xff0c;一个网站只在桌面屏幕上好看是远远不够的&#xff0c;同时也要在平板电脑和智能手机中能够良好呈现。响应式的网站是指它能够适应客户端的屏幕尺寸&#xff0c;自动响应客户端尺寸变化。在这篇文章中&#xff0c;我将向您展示在任何设备上都完美的30个华丽的响…

设计模式之装饰模式(Decorator)摘录

23种GOF设计模式一般分为三大类&#xff1a;创建型模式、结构型模式、行为模式。 创建型模式抽象了实例化过程&#xff0c;它们帮助一个系统独立于如何创建、组合和表示它的那些对象。一个类创建型模式使用继承改变被实例化的类&#xff0c;而一个对象创建型模式将实例化委托给…

解决流程自动化“最后一公里问题”,达观数据发布智能 RPA

2019 年7月 26 日&#xff0c;业界领先的人工智能企业达观数据在北京召开“达道至简”为主题的产品发布会&#xff0c;正式推出国内首款自主研发集OCR(光学字符识别)与 NLP(自然语言处理)于一体的达观智能RPA。达观数据创始人兼CEO陈运文、副总裁金克、贾学锋和联合创始人高翔携…

利用脚本生成GUID

实际上&#xff0c;可以使用一种非常简单的方法来生成 GUID&#xff0c;但这种方法近乎像是作弊。&#xff08;您可听清楚了&#xff0c;我们说的可是“近乎”。&#xff09;“Scriptlet.TypeLib”对象的设计用途是帮助您创建“Windows 脚本组件”&#xff08;实质上&#xff0…

设计模式之组合模式(Composite)摘录

23种GOF设计模式一般分为三大类&#xff1a;创建型模式、结构型模式、行为模式。 创建型模式抽象了实例化过程&#xff0c;它们帮助一个系统独立于如何创建、组合和表示它的那些对象。一个类创建型模式使用继承改变被实例化的类&#xff0c;而一个对象创建型模式将实例化委托给…

快速开发生命周期支持工具

去年有幸研究公司管理产品的软件平台,当时考虑的产品是基于业务模型之上的一个系统平台,从建模到运行、部署、维护全生命周期管理.当时就提出两个希望先实践解决的就是可复用原型的设计和使用工作流和规则引擎的协作处理询标产品.前一阵子在公司研究成本产品的成本分析和算法,一…

华人学者解开计算机领域30年难题:布尔函数敏感度猜想

整理 | 郭芮来源 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;1992年&#xff0c;布尔函数敏感度猜想&#xff08;Boolean Sensitivity&#xff09;被提出&#xff0c;这成为了理论计算机科学近三十年来最重要、最令人困惑的开放性问题之一。而近日&#xff0c;来自E…

从1.5K到18K 一个程序员的5年成长之路(二)

这一切都来自于心态CSDN&#xff1a;从开始学习&#xff0c;到学有所成和找工作&#xff0c;再到工作中遇到各种困难&#xff0c;然后获得突破&#xff0c;在整个过程中&#xff0c;能总结下你心态都有哪些变化&#xff1f;是用运用什么方法或方式进行调整&#xff1f;雷果国&a…

设计模式之享元模式(Flyweight)摘录

23种GOF设计模式一般分为三大类&#xff1a;创建型模式、结构型模式、行为模式。 创建型模式抽象了实例化过程&#xff0c;它们帮助一个系统独立于如何创建、组合和表示它的那些对象。一个类创建型模式使用继承改变被实例化的类&#xff0c;而一个对象创建型模式将实例化委托给…

你想见的大神都来AI ProCon 2019了,优惠票限时抢购开启!

如今 AI 的发展真实地面临着诸多瓶颈、尽管很多智能助手已经可以执行很多任务&#xff0c;但距离真正的人机自然交互还需要很长时间&#xff1b;强人工智能也迟迟未出现&#xff0c;不知何时才能出现&#xff1b;现有的 AI 只能做好一件事&#xff0c;Alpha Go 只会下棋&#x…

qt练习11 鼠标,按键,滚轮事件学习

源代码: http://files.cnblogs.com/hnrainll/event.zip

windows server 2008 R2上安装MRTG指南

一、实验环境 参考教程&#xff1a;http://www.netmon.org/dummies.htm http://www.docin.com/p-158415185.html MRTG中文手册&#xff1a;http://bbs.chinaunix.net/thread-1344687-1-1.html http://www.enterastream.com/whitepapers/mrtg/mrtg-manual-cap9.html 1.硬件平台 …

设计模式之外观模式(Facade)摘录

23种GOF设计模式一般分为三大类&#xff1a;创建型模式、结构型模式、行为模式。 创建型模式抽象了实例化过程&#xff0c;它们帮助一个系统独立于如何创建、组合和表示它的那些对象。一个类创建型模式使用继承改变被实例化的类&#xff0c;而一个对象创建型模式将实例化委托给…

知识图谱公开课 | 详解事件抽取与事件图谱构建

现有知识图谱大多关注于以实体为核心的静态知识&#xff0c;缺乏对于以事件为核心的动态知识的刻画和构建。如何从非结构化文本中抽取结构化的事件知识已成为眼下热门研究课题。本次公开课中&#xff0c;我们邀请到了中科院自动化所模式识别国家重点实验室助理研究员陈玉博&…

实时显示系统时间

CTime time;CString m_time;void CtimeDlg::OnBnClickedButton1(){// TODO: 在此添加控件通知处理程序代码 SetTimer(1,1000,NULL);}void CtimeDlg::OnTimer(UINT_PTR nIDEvent){// TODO: 在此添加消息处理程序代码和/或调用默认值 timeCTime::GetCurrentTime(); …

安卓手机文件管理器:360°LES文件浏览器

360度LES文件浏览器功能可谓是非常强大&#xff0c;可以对文件或文件夹进行新建、复制、剪切、删除、移动、搜索等操作。支持多标签页&#xff0c;能设置成root级别的管理器, 关联文件打开,列表或图标的形式显示&#xff0c;拖曳文件,多标签页下文件拖曳(下面有详细的讲解)&…