“单一职责”模式:
在软件组件的设计中,如果责任划分的不清晰,使用继承得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码,这时候的关键是划清责任。
经典模式:
Decorator
Bridge
动机(Motivation)
由于某种类型固有的实现逻辑,使得它们具有两个变化的维度,乃至多个维度的变化。
如何应对这种“多维度的变化”?如何利用面向对象技术来使得类型可以轻松地沿着两个乃至多个方向变化,而不引入额外定位复杂度?
示例1:
#pragma once
#include <string>
using namespace std;
class Image{};
class Messager {
public:
virtual void Login(const string& user_name, const string& password) = 0;
virtual void SendMessage(string message) = 0;
virtual void SendPictire(Image image) = 0;
virtual void PlaySound() = 0;
virtual void DrawShap() = 0;
virtual void WriteText() = 0;
virtual void Connect() = 0;
virtual ~Messager() {}
};
//平台实现
class PCMessagerbase : public Messager {
public:
virtual void PlaySound() {
//***
}
virtual void DrawShap(){
//***
}
virtual void WriteText() {
//***
}
virtual void Connect() {
//***
}
};
class MobileMessagerbase : public Messager {
public:
virtual void PlaySound() {
//===
}
virtual void DrawShap() {
//===
}
virtual void WriteText() {
//===
}
virtual void Connect() {
//===
}
};
//业务抽象
//类的数目:1+n+n*m
class PCMessagerLite : public PCMessagerbase {
public:
virtual void Login(const string& user_name, const string& password) {
PCMessagerbase::Connect();
//***
}
virtual void SendMessage(string message) {
PCMessagerbase::WriteText();
//***
}
virtual void SendPictire(Image image) {
PCMessagerbase::DrawShap();
//***
}
};
class PCMessagerPerfect : public PCMessagerbase {
public:
virtual void Login(const string& user_name, const string& password) {
PCMessagerbase::PlaySound();
//***
PCMessagerbase::Connect();
//...
}
virtual void SendMessage(string message) {
PCMessagerbase::PlaySound();
//***
PCMessagerbase::WriteText();
//...
}
virtual void SendPictire(Image image) {
PCMessagerbase::PlaySound();
//***
PCMessagerbase::DrawShap();
//...
}
};
class MobileMessagerLite : public MobileMessagerbase {
public:
virtual void Login(const string& user_name, const string& password) {
MobileMessagerbase::Connect();
//***
}
virtual void SendMessage(string message) {
MobileMessagerbase::WriteText();
//***
}
virtual void SendPictire(Image image) {
MobileMessagerbase::DrawShap();
//***
}
};
class MobileMessagerPerfect : public MobileMessagerbase {
public:
virtual void Login(const string& user_name, const string& password) {
MobileMessagerbase::PlaySound();
//***
MobileMessagerbase::Connect();
//...
}
virtual void SendMessage(string message) {
MobileMessagerbase::PlaySound();
//***
MobileMessagerbase::WriteText();
//...
}
virtual void SendPictire(Image image) {
MobileMessagerbase::PlaySound();
//***
MobileMessagerbase::DrawShap();
//...
}
};
void Process() {
//编译时装配
Messager* m = new MobileMessagerLite();
}
示例2
#pragma once
#include <string>
using namespace std;
class Image {};
class Messager {
protected:
MessagerImp* messageImp_;
public:
Messager(MessagerImp* mesagerImp) : messageImp_(mesagerImp)
{}
virtual void Login(const string& user_name, const string& password) = 0;
virtual void SendMessage(string message) = 0;
virtual void SendPictire(Image image) = 0;
virtual ~Messager() {}
};
class MessagerImp {
public:
virtual void PlaySound() = 0;
virtual void DrawShap() = 0;
virtual void WriteText() = 0;
virtual void Connect() = 0;
virtual ~MessagerImp() {}
};
//平台实现
class PCMessagerImp : public MessagerImp {
public:
virtual void PlaySound() {
//***
}
virtual void DrawShap() {
//***
}
virtual void WriteText() {
//***
}
virtual void Connect() {
//***
}
};
class MobileMessagerImp : public MessagerImp {
public:
virtual void PlaySound() {
//===
}
virtual void DrawShap() {
//===
}
virtual void WriteText() {
//===
}
virtual void Connect() {
//===
}
};
//业务抽象
//类的数目:
class MessagerLite : public Messager{
public:
MessagerLite(MessagerImp* messagerImp) : Messager(messagerImp)
{}
virtual void Login(const string& user_name, const string& password) {
messageImp_->Connect();
//***
}
virtual void SendMessage(string message) {
messageImp_->WriteText();
//***
}
virtual void SendPictire(Image image) {
messageImp_->DrawShap();
//***
}
};
class MessagerPerfect : public Messager {
public:
MessagerPerfect(MessagerImp* messagerImp) : Messager(messagerImp)
{}
virtual void Login(const string& user_name, const string& password) {
messageImp_->PlaySound();
//***
messageImp_->Connect();
//...
}
virtual void SendMessage(string message) {
messageImp_->PlaySound();
//***
messageImp_->WriteText();
//...
}
virtual void SendPictire(Image image) {
messageImp_->PlaySound();
//***
messageImp_->DrawShap();
//...
}
};
void Process() {
MobileMessagerImp* mobile_messager_imp = new MobileMessagerImp();
Messager* mesasger = new MessagerPerfect(mobile_messager_imp);
}
模式定义
将抽象部分(业务部分)与实现部分(平台实现)分离,使它们都可以独立地变化。
红色时稳定部分,蓝色时变化部分。
要点总结:
Bridge模式使用“对象 间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化,即“子类化”它们。
Bridge模式有时候类似与多继承方案,但是多继承方案往往违背单一职责原则(即一个类只有一个变化的原因),复用性较差。Bridge模式是比多继承发难更好的解决方法。
Bridge模式的应用一般在“两个非常强的变化维度”,有时一个类也有对于两个的变化维度,这时可以使用Bridge的扩展模式模式。