Published on

设计模式(7)——桥接 Bridge

Authors
  • avatar
    Name
    Leon
    Twitter

七、Bridge (桥接模式,对象结构型模式)

1. 问题:

  当一个抽象有多个实现时,通常用继承来协调它们。抽象类定义对该抽象的接口,而具体的子类则用不同方式加以实现。但是此方法有时不够灵活。继承机制将抽象部分与它的实现部分固定在一起,使得难以对抽象部分和实现部分独立地进行修改、扩充和重用。

2. 意图:

  将抽象部分与它的实现(注意这个实现的含义见思考部分)部分分离,使它们都可以独立地变化。

3. 适用:

  1. 不希望在抽象和它的实现部分之间有一个固定的绑定关系。例如这种情况可能是因为,在程序运行时刻实现部分可以被选择或者切换。
  2. 类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。

4. 类图:

5. 思考:

  抽象部分与它的实现部分分离,这里的“实现”不是指抽象基类的具体子类对抽象基类中虚函数(接口)的实现,这是和继承结合在一起的,而是指怎么去“实现”用户的需求,并且指的是通过组合(委托)的方式实现的,因此这里的实现不是指的继承基类、实现基类接口,而是指的通过对象组合实现用户的需求。使用 Bridge 模式来解决问题体现的是通过继承还是通过组合方式去实现一个功能需求。因此面向对象分析和设计中有一个原则就是:Favor Composition Over Inheritance

6. 代码实现:

  1. 首先编写一个为实现需求而设计的一个抽象基类或接口(桥梁)AbstractionImp,含有一个函数 Operation
  2. 然后编写这个基类的一些具体子类 ConcreteAbstractionImp,实现具体的 Operation
  3. 定义一个接口 Abstraction,含有同名的函数 Operation
  4. 编写更具体的接口 RefinedAbstraction 继承上一步的接口,并聚合一个抽象基类 AbstractionImp
  5. 具体接口 RefinedAbstraction 中的 Operation 调用 具体子类中 ConcreteAbstractionImp 中的 Operation

Abstraction.h

//Abstraction.h
#pragma once

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

Abstraction.cpp

// 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

//AbstractionImp.h
#pragma once

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

AbstractionImp.cpp

// 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

// main.cpp
#include "Abstraction.h"
#include "AbstractionImp.h"

#include <iostream>

using namespace::std;

int main(int argc, char* argv[]) {
	AbstractionImp* imp = new ConcreteAbstractionImpA();
	Abstraction* abs = new RefinedAbstraction(imp);
	abs->Operation();
	return 0;
}