1、定义
桥接模式(Bridge Pattern):可将一个大类或一系列紧密相关的类拆分为抽象和实现两个独立的层次结构,从而能在开发时分别使用。
2、前言
背景:
假如你有一个几何形状(Shape)类, 从它能扩展出两个子类: 圆形(Circle)和方形(Square)。
-
你希望对这样的类层次结构进行扩展以使其包含颜色, 所以你打算创建名为红色(Red)和蓝色(Blue)的形状子类。
-
但是,由于你已有两个子类,所以总共需要创建四个类才能覆盖所有组合,例如蓝色圆形(BlueCircle)和红色方形(RedSquare)。
问题:
在层次结构中新增形状和颜色将导致代码复杂程度指数增长。
- 例如添加三角形状,你需要新增两个子类,也就是每种颜色一个;
- 此后新增一种新颜色需要新增三个子类,即每种形状一个。
- 如此以往,情况会越来越糟糕。
解决方案:
问题的根本原因:我们试图在两个独立的维度(形状与颜色)上扩展形状类。这是处理类继承时常遇到的问题。
解决问题:桥接模式通过将继承改为组合的方式来解决这个问题。
- 具体来说,就是抽取其中一个维度并使之成为独立的类层次;
- 可以将颜色相关的代码抽取到拥有红色和蓝色两个子类的颜色类中;
- 然后在形状类中添加一个指向某一颜色对象的引用成员变量。
- 这样就可以在初始类中引用这个新层次的对象,从而使得一个类不必拥有所有的状态和行为。
3、结构
- 抽象部分(Abstraction)提供高层控制逻辑, 依赖于完成底层实际工作的实现对象。
- 实现部分(Implementation)为所有具体实现声明通用接口。抽象部分仅能通过在这里声明的方法与实现对象交互。抽象部分可以列出和实现部分一样的方法,但是抽象部分通常声明一些复杂行为,这些行为依赖于多种由实现部分声明的原语操作。
- 具体实现(Concrete Implementations)中包括特定于平台的代码。
- 精确抽象(Refined Abstraction)提供控制逻辑的变体。与其父类一样,它们通过通用实现接口与不同的实现进行交互。
- 通常情况下,客户端(Client)仅关心如何与抽象部分合作。但是,客户端需要将抽象对象与一个实现对象连接起来。
4、代码
Abstraction.h:
#ifndef ABSTRACTION_H_
#define ABSTRACTION_H_
#include "Implementation.h"
// 形状类
class Pen
{
public:
virtual void draw(std::string name) = 0;
void set_color(Color* color)
{
color_ = color;
}
protected:
Color* color_;
};
#endif //ABSTRACTION_H_
Implementation.h:
#ifndef IMPLEMENTATION_H_
#define IMPLEMENTATION_H_
#include<iostream>
#include<string>
// 颜色
class Color
{
public:
virtual void bepaint(std::string pen_type,std::string name) = 0;
};
#endif //IMPLEMENTATION_H_
RefinedAbstraction.h:
#ifndef REFINED_ABSTRACTION_H_
#define REFINED_ABSTRACTION_H_
#include "Abstraction.h"
// 精确抽象类: BigPen
class Bigpen:public Pen
{
void draw(std::string name)
{
std::string pen_type = "大号钢笔绘制";
color_->bepaint(pen_type, name);
}
};
// 精确抽象类: SmallPencil
class SmallPencil:public Pen
{
public:
void draw(std::string name)
{
std::string pen_type = "小号铅笔绘制";
color_->bepaint(pen_type, name);
}
};
#endif //REFINED_ABSTRACTION_H_
ConcreteImplementation.h:
#ifndef CONCRETE_IMPLEMENTATION_H_
#define CONCRETE_IMPLEMENTATION_H_
#include"Implementation.h"
class Red : public Color
{
public:
void bepaint(std::string pen_type,std::string name) override
{
std::cout << pen_type << "红色的" << name << "." << std::endl;
}
};
class Green:public Color
{
public:
void bepaint(std::string pen_type,std::string name) override
{
std::cout << pen_type << "绿色的" << name << "." << std::endl;
}
};
#endif //CONCRETE_IMPLEMENTATION_H_
main.cpp
#include"ConcreteImplementation.h"
#include"RefinedAbstraction.h"
int main()
{
//客户端根据运行时参数获取对应的Color和Pen
Color* color = new Red();
Pen* pen = new SmallPencil();
pen->set_color(color);
pen->draw("太阳");
delete color;
delete pen;
return 0;
}