案例:
现在需要在PC和Mobile两个平台实现相关的业务。
首先看一下简单的方案,直接通过类的继承来实现。
缺点:但是这个方案不满足开闭原则,当我们需要添加一种平台或者说添加一种业务实现的方案会使得类增加非常多。
class Messager{
public:
virtual void Login(QString name , QString psswd) = 0;
virtual void SendMessage(QString msg) = 0;
virtual void SendPicture(QString pic) = 0;
virtual void PlaySound() = 0;
virtual void DrawShap() = 0;
virtual void WriteTex() = 0;
virtual void Connect() = 0;
virtual ~Messager(){}
};
//平台实现
class PCMessageBase :public Messager{
public:
virtual void PlaySound() {
qDebug()<<"PC PlaySound"<<endl;
}
virtual void DrawShap() {
qDebug()<<"PC DrawShap"<<endl;
}
virtual void WriteTex() {
qDebug()<<"PC WriteTex"<<endl;
}
virtual void Connect() {
qDebug()<<"PC Connect"<<endl;
}
};
class MobileMessageBase :public Messager{
public:
virtual void PlaySound() {
qDebug()<<"Mobile PlaySound"<<endl;
}
virtual void DrawShap() {
qDebug()<<"Mobile DrawShap"<<endl;
}
virtual void WriteTex() {
qDebug()<<"Mobile WriteTex"<<endl;
}
virtual void Connect() {
qDebug()<<"Mobile Connect"<<endl;
}
};
//业务
class PCMessageBaseLite :public PCMessageBase{
public:
virtual void Login(QString name , QString psswd) {
PCMessageBase::Connect();
qDebug()<<"PC Login Lite"<<endl;
}
virtual void SendMessage(QString msg){
PCMessageBase::WriteTex();
qDebug()<<"PC SendMessage Lite"<<endl;
}
virtual void SendPicture(QString pic){
PCMessageBase::DrawShap();
qDebug()<<"PC SendPicture Lite"<<endl;
}
};
class PCMessageBasePetfect :public PCMessageBase{
public:
virtual void Login(QString name , QString psswd) {
PCMessageBase::Connect();
PCMessageBase::PlaySound();
qDebug()<<"PC Login Lite"<<endl;
}
virtual void SendMessage(QString msg){
PCMessageBase::WriteTex();
PCMessageBase::PlaySound();
qDebug()<<"PC SendMessage Lite"<<endl;
}
virtual void SendPicture(QString pic){
PCMessageBase::DrawShap();
PCMessageBase::PlaySound();
qDebug()<<"PC SendPicture Lite"<<endl;
}
};
class MobileMessageBaseLite :public MobileMessageBase{
public:
virtual void Login(QString name , QString psswd) {
MobileMessageBase::Connect();
qDebug()<<"Mobile Login Lite"<<endl;
}
virtual void SendMessage(QString msg){
MobileMessageBase::WriteTex();
qDebug()<<"Mobile SendMessage Lite"<<endl;
}
virtual void SendPicture(QString pic){
MobileMessageBase::DrawShap();
qDebug()<<"Mobile SendPicture Lite"<<endl;
}
};
class MobileMessageBasePetfect :public MobileMessageBase{
public:
virtual void Login(QString name , QString psswd) {
MobileMessageBase::Connect();
MobileMessageBase::PlaySound();
qDebug()<<"Mobile Login Lite"<<endl;
}
virtual void SendMessage(QString msg){
MobileMessageBase::WriteTex();
MobileMessageBase::PlaySound();
qDebug()<<"Mobile SendMessage Lite"<<endl;
}
virtual void SendPicture(QString pic){
MobileMessageBase::DrawShap();
MobileMessageBase::PlaySound();
qDebug()<<"Mobile SendPicture Lite"<<endl;
}
};
调用函数
PCMessageBaseLite* pclite = new PCMessageBaseLite;
PCMessageBasePetfect* pcpef = new PCMessageBasePetfect;
MobileMessageBaseLite* molite = new MobileMessageBaseLite;
MobileMessageBasePetfect* mopef = new MobileMessageBasePetfect;
pclite->Login("","");
pclite->SendMessage("");
pclite->SendPicture("");
pcpef->Login("","");
pcpef->SendMessage("");
pcpef->SendPicture("");
molite->Login("","");
molite->SendMessage("");
molite->SendPicture("");
mopef->Login("","");
mopef->SendMessage("");
mopef->SendPicture("");
第一步
将继承改为组合 ,为下面的代码
但是这里有一个问题
Messager * messager;//new MobileMessageBase /PCMessageBase
这里将来在运行时需要new MobileMessageBase /PCMessageBase,但是这个 MobileMessageBase /PCMessageBase是一个抽象类,不可以new。因为MobileMessageBase 继承自Messager,有部分方法没有完成。
class Messager{
public:
virtual void Login(QString name , QString psswd) = 0;
virtual void SendMessage(QString msg) = 0;
virtual void SendPicture(QString pic) = 0;
virtual void PlaySound() = 0;
virtual void DrawShap() = 0;
virtual void WriteTex() = 0;
virtual void Connect() = 0;
virtual ~Messager(){}
};
//平台实现
class PCMessageBase :public Messager{
public:
virtual void PlaySound() {
qDebug()<<"PC PlaySound"<<endl;
}
virtual void DrawShap() {
qDebug()<<"PC DrawShap"<<endl;
}
virtual void WriteTex() {
qDebug()<<"PC WriteTex"<<endl;
}
virtual void Connect() {
qDebug()<<"PC Connect"<<endl;
}
};
class MobileMessageBase :public Messager{
public:
virtual void PlaySound() {
qDebug()<<"Mobile PlaySound"<<endl;
}
virtual void DrawShap() {
qDebug()<<"Mobile DrawShap"<<endl;
}
virtual void WriteTex() {
qDebug()<<"Mobile WriteTex"<<endl;
}
virtual void Connect() {
qDebug()<<"Mobile Connect"<<endl;
}
};
//业务
class MessageBaseLite {
Messager * messager;//new MobileMessageBase /PCMessageBase
public:
virtual void Login(QString name , QString psswd) {
messager->Connect();
qDebug()<<"PC Login Lite"<<endl;
}
virtual void SendMessage(QString msg){
messager->WriteTex();
qDebug()<<"PC SendMessage Lite"<<endl;
}
virtual void SendPicture(QString pic){
messager->DrawShap();
qDebug()<<"PC SendPicture Lite"<<endl;
}
};
class MessageBasePetfect{
Messager * messager;//new MobileMessageBase /PCMessageBase
public:
virtual void Login(QString name , QString psswd) {
messager->Connect();
messager->PlaySound();
qDebug()<<"PC Login Lite"<<endl;
}
virtual void SendMessage(QString msg){
messager->WriteTex();
messager->PlaySound();
qDebug()<<"PC SendMessage Lite"<<endl;
}
virtual void SendPicture(QString pic){
messager->DrawShap();
messager->PlaySound();
qDebug()<<"PC SendPicture Lite"<<endl;
}
};
第二步
拆分基础类 将功能分开
class MessagerImp{
public:
virtual void PlaySound() = 0;
virtual void DrawShap() = 0;
virtual void WriteTex() = 0;
virtual void Connect() = 0;
virtual ~MessagerImp(){}
};
class Messager{
protected:
MessagerImp * messagerImp;//new MobileMessageBase /PCMessageBase
public:
Messager( MessagerImp * imp):messagerImp(imp){}
virtual void Login(QString name , QString psswd) = 0;
virtual void SendMessage(QString msg) = 0;
virtual void SendPicture(QString pic) = 0;
virtual ~Messager(){}
};
//平台实现
class PCMessageBase :public MessagerImp{
public:
virtual void PlaySound() {
qDebug()<<"PC PlaySound"<<endl;
}
virtual void DrawShap() {
qDebug()<<"PC DrawShap"<<endl;
}
virtual void WriteTex() {
qDebug()<<"PC WriteTex"<<endl;
}
virtual void Connect() {
qDebug()<<"PC Connect"<<endl;
}
};
class MobileMessageBase :public MessagerImp{
public:
virtual void PlaySound() {
qDebug()<<"Mobile PlaySound"<<endl;
}
virtual void DrawShap() {
qDebug()<<"Mobile DrawShap"<<endl;
}
virtual void WriteTex() {
qDebug()<<"Mobile WriteTex"<<endl;
}
virtual void Connect() {
qDebug()<<"Mobile Connect"<<endl;
}
};
//业务
class MessageBaseLite :public Messager{
public:
MessageBaseLite(MessagerImp* imp):Messager(imp){}
virtual void Login(QString name , QString psswd) {
messagerImp->Connect();
qDebug()<<" Login Lite"<<endl;
}
virtual void SendMessage(QString msg){
messagerImp->WriteTex();
qDebug()<<" SendMessage Lite"<<endl;
}
virtual void SendPicture(QString pic){
messagerImp->DrawShap();
qDebug()<<" SendPicture Lite"<<endl;
}
};
class MessageBasePetfect :public Messager{
public:
MessageBasePetfect(MessagerImp* imp):Messager(imp){}
virtual void Login(QString name , QString psswd) {
messagerImp->Connect();
messagerImp->PlaySound();
qDebug()<<" Login Lite"<<endl;
}
virtual void SendMessage(QString msg){
messagerImp->WriteTex();
messagerImp->PlaySound();
qDebug()<<" SendMessage Lite"<<endl;
}
virtual void SendPicture(QString pic){
messagerImp->DrawShap();
messagerImp->PlaySound();
qDebug()<<" SendPicture Lite"<<endl;
}
};