设计模式
工厂模式 :?设计模式之工厂模式-CSDN博客
迭代器模式:设计模式之迭代器模式-CSDN博客
适配器模式:设计模式之适配器模式-CSDN博客
过滤器模式:设计模式之过滤器模式-CSDN博客
单例模式:设计模式之单例模式-CSDN博客
观察者模式:设计模式之观察者模式-CSDN博客
空对象模式:设计模式之空对象模式-CSDN博客
桥接模式:设计模式之桥接模式-CSDN博客
目录
????????桥接模式是一种结构性设计模式;桥接模式是将抽象和实现解耦,使两者可以独立的变化。这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类,这两种类型的类可被结构化改变而互不影响。桥接模式的目的是将抽象与实现分离,使它们可以独立地变化,该模式通过将一个对象的抽象部分与它的实现部分分离,使它们可以独立地改变。它通过组合(Composition)的方式,而不是继承(Inheritance)的方式,将抽象和实现的部分连接起来。
桥接模式(Bridge Pattern)的UML类图如下所示:
类图主要包括以下几部分:
抽象(Abstraction):定义抽象接口,通常包含对实现接口的引用。
扩展抽象(Refined Abstraction):对抽象的扩展,可以是抽象类的子类或具体实现类,如类图中的RefinedAbstractionA和RefinedAbstractionB。
实现(Implementor):定义实现接口,提供基本操作的接口。
具体实现(Concrete Implementor):实现实现接口的具体类,如类图中的ConcreteImplementorA和ConcreteImplementorB。
以图形绘制和图像渲染为例,绘制和渲染是两个维度的东西,定义了两个渲染器对象,向量渲染器和光栅渲染器,图形也定义了矩形和圆,代码如下:
class IRenderer
{
public:
virtual void render(float x, float y) = 0;
};
class VectorRenderer : public IRenderer
{
public:
void render(float x, float y) override {
std::cout << "VectorRenderer pos : " << x << ", " << y << std::endl;
}
};
class RasterRenderer : public IRenderer
{
public:
void render(float x, float y) override {
std::cout << "RasterRenderer pos : " << x << ", " << y << std::endl;
}
};
class IShape {
public:
explicit IShape(IRenderer* pRenderer) : m_pRenderer(pRenderer) {}
public:
virtual void draw() = 0;
protected:
IRenderer* m_pRenderer;
};
class CRetangle : public IShape
{
public:
explicit CRetangle(IRenderer* pRenderer, float x, float y, float width, float high)
: IShape(pRenderer), m_x(x), m_y(y), m_width(width), m_high(high) {}
public:
void draw() override {
m_pRenderer->render(m_x, m_y);
}
private:
float m_x;
float m_y;
float m_width;
float m_high;
};
class CCirle : public IShape
{
public:
explicit CCirle(IRenderer* pRenderer, float x, float y, float r)
: IShape(pRenderer), m_x(x), m_y(y), m_r(r) {}
public:
void draw() override {
m_pRenderer->render(m_x, m_y);
}
private:
float m_x;
float m_y;
float m_r;
};
测试程序如下:
int main()
{
std::unique_ptr<IRenderer> pVectorRenderer(new VectorRenderer);
std::unique_ptr<IRenderer> pRasterRenderer(new RasterRenderer);
std::unique_ptr<IShape> pRetangleA(new CRetangle(pVectorRenderer.get(), 3, 5, 6, 8));
std::unique_ptr<IShape> pRetangleB(new CRetangle(pRasterRenderer.get(), 1, 2, 9, 8));
std::unique_ptr<IShape> pCirleA(new CCirle(pVectorRenderer.get(), 23, 5, 8));
std::unique_ptr<IShape> pCirleB(new CCirle(pRasterRenderer.get(), 34, 88, 9));
pRetangleA->draw();
pRetangleB->draw();
pCirleA->draw();
pCirleB->draw();
}
在这个例子中,IRenderer定义了实现化接口,VectorRenderer 和 RasterRenderer是具体的实现。IShape是抽象化,它通过组合 IRenderer来与具体实现解耦。通过使用桥接模式,我们可以在不修改 CRetangle,CCirle代码的情况下,轻松地支持不同的渲染器实现。
1)如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
2)对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。
3)当需要在一个系统中灵活地切换不同的算法或策略时,可以使用桥接模式来实现算法或策略的切换和组合。
4)需要通过组合的方式在运行时对算法进行选择时,可以使用桥接模式来避免使用多重条件语句。
优点:
1)? 抽象与实现分离
这也是桥梁模式的主要特点,它完全是为了解决继承的缺点而提出的设计模式。在该模式下,实现可以不受抽象的约束,不用再绑定在一个固定的抽象层次上。
2)? 降低了系统的耦合度
由于抽象和实现是分开的,因此抽象和实现之间的耦合度大大降低,这使得代码更容易维护和修改。
3)? 提高了代码的可读性和可维护性
由于抽象和实现是分开的,因此代码的结构更加清晰,可读性和可维护性更高。
4)? 增加了代码的重用性
桥接模式使得抽象和实现可以独立扩展,因此可以在不同的场景中重用相同的实现或抽象。
然而,桥接模式也存在一些缺点:
1) 不希望或不适用使用继承的场景
例如继承层次过渡、无法更细化设计颗粒等场景,需要考虑使用桥梁模式。
2) 接口或抽象类不稳定的场景
明知道接口不稳定还想通过实现或继承来实现业务需求,那是得不偿失的,也是比较失败的做法。
3) 重用性要求较高的场景。
设计的颗粒度越细,则被重用的可能性就越大,而采用继承则受父类的限制,不可能出现太细的颗粒度。