▷由于某些类型的固有的实现逻辑,使得它们具有两个变化的维度,乃至多个纬度的变化。
▷如何应对这种“多维度的变化”?如何利用面向对象技术来使得类型可以轻松地沿着两个乃至多个方向变化,而不引入额外的复杂度?
将抽象部分(业务功能)与实现部分(平台实现)分离,使它们都可以独立地变化。
——《设计模式:可复用面向对象软件的基础》
▷Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。所谓抽象和实现沿着各自纬度的变化,即“子类化”它们。
▷Bridge模式有时候类似于多继承方案,但是多继承方案往往违背单一职责原则(即一个类只有一个变化的原因),复用性比较差。Bridge模式是比多继承方案更好的解决方法。
▷Bridge模式的应用一般在“两个非常强的变化维度”,有时一个类也有多于两个的变化维度,这时可以使用Bridge的扩展模式。
你打算彻底改革你的“极限休息室”,正为一个新的人体工学且接口友好的电视遥控器编程。你要使用好的OO技能,让所有的遥控器基于相同的抽象,而对此抽象又做出许多不同的实现一每 部不同型号的电视都有自己的遥控器实现。
你不会第一次就做对遥控器的用户界面。事实上,你希望随着可用性数据收集得越来越丰富的同时,持续改良遥控器。所以你的两难之处就在于:遥控器会改变,而电视机也会改变。你已经将用户界面抽象出来,所以可以根据不同的电视机改变它的实现。事情还不只这样,随着使用时间的增长用户会对此界面提出一-些想法,你还必须应对他们的反馈来改变抽象。所以你要如何建立-一个OO设计,能够改变实现和抽象呢?
桥接模式通过将实现和抽象放在两个不同的类层次中而使它们可以独立改变。
现在你有了两个层次结构,其中一个是遥控器,而另一个是平台特定的电视机实现。有了桥接的存在,你就可以独立地改变这两个层次。
//TV.h
// 电视机,提供抽象方法
#ifndef BRIDGE_TV_H
#define BRIDGE_TV_H
class TV {
public:
TV(void);
virtual ~TV(void);
virtual void on() = 0 ;
virtual void off() = 0 ;
virtual void tuneChannel() = 0 ;
};
#endif //BRIDGE_TV_H
//TV.cpp
#include "tv.h"
TV::TV(void)
{
}
TV::~TV()
{
}
//rca.h
//RCA电视机
#ifndef BRIDGE_RCA_H
#define BRIDGE_RCA_H
#include "tv.h"
#include
class RCA : public TV{
public:
RCA();
~RCA();
void on() override;
void off() override;
void tuneChannel() override;
void print(){ std::cout << "RCA" << std::endl;}
};
#endif //BRIDGE_RCA_H
//rca.cpp
#include "rca.h"
#include
RCA::RCA(){}
RCA::~RCA() {}
void RCA::on()
{
std:: cout << "RCA电视机已打开" << std:: endl;
}
void RCA::off()
{
std:: cout << "RCA电视机已关闭" << std:: endl;
}
void RCA::tuneChannel()
{
std:: cout << "RCA电视机换频道" << std:: endl;
}
//Sony.h
//Sony电视机
#ifndef BRIDGE_SONY_H
#define BRIDGE_SONY_H
#include "tv.h"
class Sony : public TV{
public:
Sony();
~Sony();
void on() override;
void off() override;
void tuneChannel() override;
};
#endif //BRIDGE_SONY_H
//Sony.cpp
#include "sony.h"
#include
Sony::Sony(){}
Sony::~Sony(){}
void Sony::on()
{
std:: cout << "Sony电视机已打开" << std:: endl;
}
void Sony::off()
{
std:: cout << "Sony电视机已关闭" << std:: endl;
}
void Sony::tuneChannel()
{
std:: cout << "Sony电视机换频道" << std:: endl;
}
// remotecontrol.h
// 抽象概念中的遥控器,扮演抽象化角色
#ifndef BRIDGE_REMOTECONTROL_H
#define BRIDGE_REMOTECONTROL_H
#include "tv.h"
class RemoteControl {
protected:
//字段
TV* implementor;
public:
RemoteControl();
virtual ~RemoteControl();
void Implementor(TV* value); //属性
virtual void on(); // 开电视机,这里抽象类中不再提供实现了,而是调用实现类中的实现
virtual void off(); // 关电视机
virtual void turneChannel(); //换频道
};
#endif //BRIDGE_REMOTECONTROL_H
// remotecontrol.cpp
#include "remotecontrol.h"
RemoteControl::RemoteControl(){}
RemoteControl::~RemoteControl(){}
void RemoteControl::Implementor(TV* value)
{
implementor = value;
}
void RemoteControl::on()
{
implementor->on();
}
void RemoteControl::off()
{
implementor->off();
}
void RemoteControl::turneChannel()
{
implementor->tuneChannel();
}
//concreteremote.h
//具体遥控器
#ifndef BRIDGE_CONCRETEREMOTE_H
#define BRIDGE_CONCRETEREMOTE_H
#include "remotecontrol.h"
class ConcreteRemote : public RemoteControl {
public:
ConcreteRemote();
~ConcreteRemote();
void turneChannel() override ;
};
#endif //BRIDGE_CONCRETEREMOTE_H
//concreteremote.cpp
#include "concreteremote.h"
#include
ConcreteRemote::ConcreteRemote(){}
ConcreteRemote::~ConcreteRemote(){}
void ConcreteRemote::turneChannel()
{
implementor->tuneChannel();
}
6.测试:
//main.cpp
#include
#include "concreteremote.h"
#include "sony.h"
#include "rca.h"
int main() {
// 创建一个遥控器
RemoteControl* remoteControl = new ConcreteRemote();
// RCA电视机
TV* r = new RCA();
remoteControl->Implementor(r);
remoteControl->on();
remoteControl->turneChannel();
remoteControl->off();
// Sony电视机
TV* s = new Sony();
remoteControl->Implementor(s);
remoteControl->on();
remoteControl->turneChannel();
remoteControl->off();
delete r;
delete s;
return 0;
}
欢迎关注公众号:c_302888524
发送:“设计模式:可复用面向对象软件的基础” 获取电子书