0
点赞
收藏
分享

微信扫一扫

桥模式 Bridge

“单一职责”模式:

  • 在软件组件的设计中,如果责任划分的不清晰,使用继承得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码,这时候的关键是划清责任。
  • 典型模式
  1. Decorator
  2. Bridge

动机(Motivation)

  • 由于某些类型的固有的实现逻辑,使得它们具有两个变化的维度,乃至多个纬度的变化。
  • 如何应对这种“多维度的变化”?如何利用面向对象技术来使得类型可以轻松地沿着两个乃至多个方向变化,而不引入额外的复杂度?

代码示例

装配式编译(伪代码):

class Messager{
public:
virtual void Login(string username, string password)=0;
virtual void SendMessage(string message)=0;
virtual void SendPicture(Image image)=0;

virtual void PlaySound()=0;
virtual void DrawShape()=0;
virtual void WriteText()=0;
virtual void Connect()=0;

virtual ~Messager(){}
};


//平台实现

class PCMessagerBase : public Messager{
public:

virtual void PlaySound(){
//**********
}
virtual void DrawShape(){
//**********
}
virtual void WriteText(){
//**********
}
virtual void Connect(){
//**********
}
};

class MobileMessagerBase : public Messager{
public:

virtual void PlaySound(){
//==========
}
virtual void DrawShape(){
//==========
}
virtual void WriteText(){
//==========
}
virtual void Connect(){
//==========
}
};



//业务抽象

class PCMessagerLite : public PCMessagerBase {
public:

virtual void Login(string username, string password){

PCMessagerBase::Connect();
//........
}
virtual void SendMessage(string message){

PCMessagerBase::WriteText();
//........
}
virtual void SendPicture(Image image){

PCMessagerBase::DrawShape();
//........
}
};



class PCMessagerPerfect : public PCMessagerBase {
public:
virtual void Login(string username, string password){

PCMessagerBase::PlaySound();
//********
PCMessagerBase::Connect();
//........
}
virtual void SendMessage(string message){

PCMessagerBase::PlaySound();
//********
PCMessagerBase::WriteText();
//........
}
virtual void SendPicture(Image image){

PCMessagerBase::PlaySound();
//********
PCMessagerBase::DrawShape();
//........
}
};


class MobileMessagerLite : public MobileMessagerBase {
public:

virtual void Login(string username, string password){

MobileMessagerBase::Connect();
//........
}
virtual void SendMessage(string message){

MobileMessagerBase::WriteText();
//........
}
virtual void SendPicture(Image image){

MobileMessagerBase::DrawShape();
//........
}
};


class MobileMessagerPerfect : public MobileMessagerBase {
public:

virtual void Login(string username, string password){

MobileMessagerBase::PlaySound();
//********
MobileMessagerBase::Connect();
//........
}
virtual void SendMessage(string message){

MobileMessagerBase::PlaySound();
//********
MobileMessagerBase::WriteText();
//........
}
virtual void SendPicture(Image image){

MobileMessagerBase::PlaySound();
//********
MobileMessagerBase::DrawShape();
//........
}
};


void Process(){
//编译时装配
Messager *m =
new MobileMessagerPerfect();
}

编译时装配:

基本思想,继承转组合。

#include <iostream>
#include <string>

using namespace std;

class MessagerImp;

/*这里拆分转化为组合*/
class Messager {
public:
Messager(MessagerImp *mImp):messagerImp(mImp){}
virtual ~Messager() {}
protected:
// 重构理论:不同的派生类有同样的字段,把它往上提到基类。
MessagerImp* messagerImp;//... 以后各种变化的情况
public:
virtual void Login(string username, string password) = 0;
virtual void SendMessage(string message) = 0;
virtual void SendPicture(string image) = 0;
};

class MessagerImp {
public:
virtual void PlaySound() = 0;
virtual void DrawShape() = 0;
virtual void WriteText() = 0;
virtual void Connect() = 0;

virtual ~MessagerImp() {}
};


//平台实现 n
class PCMessagerImp : public MessagerImp {
public:
virtual void PlaySound() {
//**********
cout << "PC 端放声音" << endl;
}
virtual void DrawShape() {
//**********
cout << "PC 端画图" << endl;
}
virtual void WriteText() {
//**********
cout << "PC 端显示文案" << endl;
}
virtual void Connect() {
//**********
cout << "PC 端网络连接" << endl;
}
};

class MobileMessagerImp : public MessagerImp {
public:
virtual void PlaySound() {
//==========
cout << "移动端放声音" << endl;
}
virtual void DrawShape() {
//==========
cout << "移动端画图" << endl;
}
virtual void WriteText() {
//==========
cout << "移动端显示文案" << endl;
}
virtual void Connect() {
//==========
cout << "移动端网络连接" << endl;
}
};


//业务抽象 m

//类的数目:1+n+m

class MessagerLite :public Messager { // 轻巧版
public:
MessagerLite(MessagerImp *mImp):Messager(mImp){}

virtual void Login(string username, string password) {
messagerImp->Connect();
std::cout << username << "已登录" << endl;
//........
}
virtual void SendMessage(string message) {
messagerImp->WriteText();
//........
}
virtual void SendPicture(string image) {
messagerImp->DrawShape();
//........
}
};


class MessagerPerfect :public Messager { // 完整版
public:
MessagerPerfect(MessagerImp *mImp) :Messager(mImp) {}
virtual void Login(string username, string password) {
messagerImp->PlaySound();
//********
messagerImp->Connect();
//........
std::cout << username << "已登录" << endl;
}
virtual void SendMessage(string message) {

messagerImp->PlaySound();
//********
messagerImp->WriteText();
//........
}
virtual void SendPicture(string image) {

messagerImp->PlaySound();
//********
messagerImp->DrawShape();
//........
}
};

void Process() {
//运行时装配
MessagerImp* mImp = new PCMessagerImp(); // PC端
Messager *m = new MessagerLite(mImp);
m->Login("周杰伦", "123"); //登录
delete m; m = nullptr;
cout << endl;
m = new MessagerPerfect(mImp);
m->Login("周杰伦", "123"); //登录

delete mImp; mImp = nullptr;
delete m; m = nullptr;
}


int main()
{
Process();

getchar();
return 0;
}

输出:

PC 端网络连接
周杰伦已登录

PC 端放声音
PC 端网络连接
周杰伦已登录

类图

桥模式  Bridge_网络连接

模式定义

将抽象部分(业务功能)与实现部分(平台实现)分离,使它们都可以独立地变化。 ——《设计模式》GoF

要点总结

  • Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固 有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。所谓抽象和实现沿着各自纬度的变化,即“子类化”它们。
  • Bridge模式有时候类似于多继承方案,但是多继承方案往往违背单一职责原则(即一个类只有一个变化的原因),复用性比较差。Bridge模式是比多继承方案更好的解决方法。
  • Bridge模式的应用一般在“两个非常强的变化维度”,有时一个 类也有多于两个的变化维度,这时可以使用Bridge的扩展模式。


参考:GeekBand



举报

相关推荐

0 条评论