工程源码:
c++设计模式-结构型模式-桥接模式https://download.csdn.net/download/qq_40788199/85620432码云:
c++设计模式-结构型模式-桥接模式https://gitee.com/gongguixing/c-design-mode.git
1、桥接模式的定义与特点
桥接(Bridge)模式的定义如下:将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。
桥接(Bridge)模式的优点是:
- 抽象与实现分离,扩展能力强
- 符合开闭原则
- 符合合成复用原则
- 其实现细节对客户透明
缺点是:由于聚合关系建立在抽象层,要求开发者针对抽象化进行设计与编程,能正确地识别出系统中两个独立变化的维度,这增加了系统的理解与设计难度。
2、桥接模式的结构与实现
可以将抽象化部分与实现化部分分开,取消二者的继承关系,改用组合关系。
1. 模式的结构
桥接(Bridge)模式包含以下主要角色。
- 抽象化(Abstraction)角色:定义抽象类,并包含一个对实现化对象的引用。
- 扩展抽象化(Refined Abstraction)角色:是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。
- 实现化(Implementor)角色:定义实现化角色的接口,供扩展抽象化角色调用。
- 具体实现化(Concrete Implementor)角色:给出实现化角色接口的具体实现。
3、代码实现
3.1实现化角色
#ifndef IMPLEMENTOR_H
#define IMPLEMENTOR_H
//实现化角色
class Implementor
{
public:
virtual ~Implementor() {}
virtual void OperationImpl() = 0;
};
#endif // IMPLEMENTOR_H
3.2具体实现化角色A
#ifndef CONCRETEIMPLEMENTORA_H
#define CONCRETEIMPLEMENTORA_H
#include "implementor.h"
//具体实现化角色 A
class ConcreteImplementorA : public Implementor
{
public:
ConcreteImplementorA();
void OperationImpl() override;
};
#endif // CONCRETEIMPLEMENTORA_H
#include "concreteimplementora.h"
#include"iostream"
ConcreteImplementorA::ConcreteImplementorA()
{
}
void ConcreteImplementorA::OperationImpl()
{
std::cout << "I am the ConcreteImplementorA." << std::endl;
}
3.2具体实现化角色B
#ifndef CONCRETEIMPLEMENTORB_H
#define CONCRETEIMPLEMENTORB_H
#include "implementor.h"
//具体实现化角色 B
class ConcreteImplementorB : public Implementor
{
public:
ConcreteImplementorB();
void OperationImpl() override;
};
#endif // CONCRETEIMPLEMENTORB_H
#include "concreteimplementorb.h"
#include <iostream>
ConcreteImplementorB::ConcreteImplementorB()
{
}
void ConcreteImplementorB::OperationImpl()
{
std::cout << "I am the ConcreteImplementorB." << std::endl;
}
3.4抽象化角色
#include "implementor.h"
//抽象化角色
class Abstraction
{
public:
virtual ~ Abstraction() {}
// 设置实现化角色指针
virtual void setImple(Implementor *p) = 0;
// 操作实现化角色
virtual void Operation() = 0;
};
#endif // ABSTRACTION_H
3.5拓展抽象画角色
#include "abstraction.h"
//扩展抽象化角色
class RefinedAbstraction : public Abstraction
{
public:
RefinedAbstraction();
void setImple(Implementor *p) override;
void Operation() override;
private:
Implementor *m_Imple;
};
#endif // REFINEDABSTRACTION_H
#include "refinedabstraction.h"
#include <iostream>
RefinedAbstraction::RefinedAbstraction()
{
m_Imple = NULL;
}
void RefinedAbstraction::setImple(Implementor *p)
{
m_Imple = p;
}
void RefinedAbstraction::Operation()
{
std::cout << "I am the RefinedAbstraction." << std::endl;
m_Imple->OperationImpl();
}
3.6 调用示例
#include <iostream>
#include "concreteimplementora.h"
#include "concreteimplementorb.h"
#include "refinedabstraction.h"
int main()
{
//将抽象与实现分离,使它们可以独立变化
// 实现化角色A
Implementor * pImple = new ConcreteImplementorA();
// 抽象化角色
Abstraction * pAbs = new RefinedAbstraction();
// 设置实现化角色指针,实现化角色独立变化
pAbs->setImple(pImple);
// 操作实现化角色
pAbs->Operation();
delete pImple;
pImple = NULL;
std::cout << std::endl;
pImple = new ConcreteImplementorB();
// 设置实现化角色指针,实现化角色独立变化
pAbs->setImple(pImple);
// 操作实现化角色
pAbs->Operation();
delete pImple;
delete pAbs;
return 0;
}
桥接模式的应用场景
当一个类内部具备两种或多种变化维度时,使用桥接模式可以解耦这些变化的维度,使高层代码架构稳定。
桥接模式通常适用于以下场景。
- 当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时。
- 当一个系统不希望使用继承或因为多层次继承导致系统类的个数急剧增加时。
- 当一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性时。
桥接模式的一个常见使用场景就是替换继承。我们知道,继承拥有很多优点,比如,抽象、封装、多态等,父类封装共性,子类实现特性。继承可以很好的实现代码复用(封装)的功能,但这也是继承的一大缺点。