设计模式【6】——桥接模式(Bridge 模式)

文章目录

  • 前言
  • 一、桥接模式(Bridge 模式)
  • 二、具体源码
    • 1.AbstractionImp.h
    • 2.AbstractionImp.cpp
    • 3.Abstraction.h
    • 4.Abstraction.cpp
    • 5.main.cpp
  • 三、运行结果
  • 总结


前言

在开发过程中大家肯定都遇到过这样的问题:
1)客户给了你一个需求,于是使用一个类来实现(A);
2)客户需求变化,有两个算法实现功能,于是改变设计,我们通过一个抽象的基类,再定义两个具体类实现两个不同的算法(A1 和 A2);
3)客户又告诉我们说对于不同的操作系统,于是再抽象一个层次,作为一个抽象基类A0,在分别为每个操作系统派生具体类(A00 和 A01,其中 A00 表示原来的类 A)实现不同操作系统上的客户需求,这样我们就有了一共 4 个类。
4)可能用户的需求又有变化,比如说又有了一种新的算法………
5)我们陷入了一个需求变化的郁闷当中,也因此带来了类的迅速膨胀。
Bridge 模式则正是解决了这类问题。


一、桥接模式(Bridge 模式)

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

二、具体源码

1.AbstractionImp.h

代码如下(示例):

#pragma once

#ifndef _ABSTRACTIONIMP_H_
#define _ABSTRACTIONIMP_H_ 

#include 

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_

2.AbstractionImp.cpp

代码如下(示例):

#include "AbstractionImp.h"

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;
}

3.Abstraction.h

代码如下(示例):

#ifndef _ABSTRACTION_H_ 
#define _ABSTRACTION_H_ 

#include "AbstractionImp.h"

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_

4.Abstraction.cpp

代码如下(示例):

#include "Abstraction.h" 

using namespace std;

Abstraction::Abstraction()
{
}

Abstraction::~Abstraction()
{
}

RefinedAbstraction::RefinedAbstraction(AbstractionImp* imp)
{
  _imp = imp;
}

RefinedAbstraction::~RefinedAbstraction()
{
}

void RefinedAbstraction::Operation()
{
  _imp->Operation();
}

5.main.cpp

代码如下(示例):

#include "Abstraction.h" 
#include "AbstractionImp.h"

using namespace std;

int main(int argc, char* argv[])
{
  AbstractionImp* imp = new ConcreteAbstractionImpA();
  Abstraction* abs = new RefinedAbstraction(imp);

  abs->Operation();

  AbstractionImp* imp1 = new ConcreteAbstractionImpB();
  abs = new RefinedAbstraction(imp1);

  abs->Operation();

  return 0;
}

三、运行结果

Bridge 模式运行结果如下:
设计模式【6】——桥接模式(Bridge 模式)_第2张图片


总结

Bridge 模式将抽象和实现分别独立实现,在代码中就是 Abstraction 类和 AbstractionImp类。Bridge 是设计模式中比较复杂和难理解的模式之一,其本质就是使用组合(委托)的方式将抽象和实现彻底地解耦,这样的好处是抽象和实现可以分别独立地变化,系统的耦合性也得到了很好的降低。
正如书中所说的,使用 Bridge 模式和使用带来问题方式的解决方案的根本区别在于是通过继承还是通过组合的方式去实现一个功能需求。因此面向对象分析和设计中有一个原则就是:Favor Composition Over Inheritance。其原因也正在这里。


本文参考《设计模式精解-GoF 23 种设计模式解析附 C++实现源码》,对内容进行整理,方便大家学习。如想学习详细内容,请参考此书。

你可能感兴趣的:(设计模式,设计模式,桥接模式,uml)