桥接模式
动机
由于某些类型的固有的实现逻辑,使得它们具有两个变化的维度,乃至多个纬度的变化。
如何应对这种“多维度的变化”?
如何利用面向对象技术来使得类型可以轻松地沿着两个乃至多个方向变化,而不引入额外的复杂度?
解决方法
将抽象部分(业务功能)与实现部分(平台实现)分离,使它们都可以独立地变化。
例子
制作一个通讯工具:
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();
}
改进(拆分基类出一个接口):
class Messager
{
protected:
MessagerImp *messagerImp; // ...
public:
virtual void Login(string username, string password) = 0;
virtual void SendMessage(string message) = 0;
virtual void SendPicture(Image image) = 0;
virtual ~Messager(){}
};
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()
{
// **********
}
virtual void DrawShape()
{
// **********
}
virtual void WriteText()
{
// **********
}
virtual void Connect()
{
// **********
}
};
class MobileMessagerImp: public MessagerImp
{
public:
virtual void PlaySound()
{
// ==========
}
virtual void DrawShape()
{
// ==========
}
virtual void WriteText()
{
// ==========
}
virtual void Connect()
{
// ==========
}
};
// 业务抽象 m
class MessagerLite: public Messager
{
public:
virtual void Login(string username, string password)
{
messagerImp->Connect();
//........
}
virtual void SendMessage(string message)
{
messagerImp->WriteText();
//........
}
virtual void SendPicture(Image image)
{
messagerImp->DrawShape();
//........
}
};
class MessagerPerfect: public Messager
{
public:
virtual void Login(string username, string password)
{
messagerImp->PlaySound();
// ********
messagerImp->Connect();
// ........
}
virtual void SendMessage(string message)
{
messagerImp->PlaySound();
// ********
messagerImp->WriteText();
// ........
}
virtual void SendPicture(Image image)
{
messagerImp->PlaySound();
// ********
messagerImp->DrawShape();
// ........
}
};
// 类的数目:1+n+m
void Process()
{
// 运行时装配
MessagerImp *mImp = new PCMessagerImp();
Messager *m = new Messager(mImp);
}
优缺点
优点:抽象和实现的分离。优秀的扩展能力。实现细节对客户透明。
缺点:桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。