1、桥模式
1)定义
将抽象部分(业务功能)与实现部分(平台实现)分离,使它们都可以独立地变化。
2)动机(motivation)
> 由于某些类型的固有的实现逻辑,使得它们具有两个变化的维度,乃至于多个维度的变化。
> 如何应对这种“多维度的变化”?如何利用面向对象技术来使得类型可以轻松地沿着两个乃至多个方向变化,而不引入额外的复杂度?
3)类图
4)代码实现
#include<iostream>
#include<memory>
#include<string>
using namespace std;
// 消息框具体实现(此部分为具体实现:声音、形状、写文本框、连接等)
class MessagerImp {
public:
virtual ~MessagerImp() {}
virtual void PlaySound() = 0;
virtual void DrawShape() = 0;
virtual void WriteText() = 0;
virtual void Connect() = 0;
};
// 此消息框(实现基本属性:登陆、发送消息等)
class Messager {
protected:
unique_ptr<MessagerImp> pmb; //=new PCMessager(); MobileMessager();
public:
Messager(unique_ptr<MessagerImp> _pmb) :pmb(std::move(_pmb)) {}
virtual ~Messager() {}
virtual void Login(string username, string password) = 0; // 登陆
virtual void SendMessage(string message) = 0; // 发送消息
virtual void SendPicture(string image) = 0; // 发送图片
};
//1+1+n+m
//平台实现
class PCMessager : public MessagerImp {
public:
void PlaySound() override {
std::cout << "***********PCMessager PlaySound***********" << std::endl;
}
void DrawShape() override {
std::cout << "***********PCMessager DrawShape***********" << std::endl;
}
void WriteText() override {
std::cout << "***********PCMessager WriteText***********" << std::endl;
}
void Connect() override {
std::cout << "***********PCMessager Connect***********" << std::endl;
}
};
class MobileMessager : public MessagerImp {
public:
void PlaySound() override {
std::cout << "***********MobileMessager PlaySound***********" << std::endl;
}
void DrawShape() override {
std::cout << "***********MobileMessager DrawShape***********" << std::endl;
}
void WriteText() override {
std::cout << "***********MobileMessager WriteText***********" << std::endl;
}
void Connect() override {
std::cout << "***********MobileMessager Connect***********" << std::endl;
}
};
//业务抽象
class MessagerLite : public Messager {
public:
MessagerLite(unique_ptr<MessagerImp> _pmb) :Messager(std::move(_pmb)) {}
void Login(string username, string password) override {
pmb->Connect();
//........
}
void SendMessage(string message) override {
pmb->WriteText();
//........
}
void SendPicture(string image) override {
pmb->DrawShape();
//........
}
};
class MessagerPerfect : public Messager {
public:
MessagerPerfect(unique_ptr<MessagerImp> _pmb) :Messager(std::move(_pmb)) {}
void Login(string username, string password) override {
pmb->PlaySound();
//********
pmb->Connect();
//........
}
void SendMessage(string message) override {
pmb->PlaySound();
//********
pmb->WriteText();
//........
}
void SendPicture(string image) override {
pmb->PlaySound();
//********
pmb->DrawShape();
//........
}
};
void Process() {
//运行时装配
unique_ptr<MessagerImp> pMsgImp =
std::make_unique<MobileMessager>();
unique_ptr<Messager> pMsg =
std::make_unique<MessagerPerfect>(std::move(pMsgImp));
pMsg->Login("xiaoming","123456");
pMsg->SendMessage("Hello world.");
pMsg->SendPicture("000000");
}
int main()
{
Process();
system("pause");
return 0;
}
5)总结
> Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。所谓抽象和实现沿着各自维度的变化,即“子类化”它们。
> Bridge模式有时候类似于多继承方案,但是多继承方案往往违背单一职责原则(即一个类只有一个变化的原因),复用性比较差,Bridge模式是比多继承方案更好的解决方法。
> Bridge模式的应用一般在“两个非常强的变化维度”,有时一个类也有多于两个变化的维度,这时可以使用Bridge的扩展模式。