目录
一、代理模式
二、装饰模式
三、外观模式
四、适配器模式
通过一个代理类,来控制对这个对象的访问。
类别 | 描述 |
适用场景 |
|
优点 |
|
缺点 |
|
无代理模式,人人可具备权限
#include
using namespace std;//提供一种代理来控制对其他对象的访问class AbstraactCommonInterface {
public:virtual void run() = 0;};//我已经写好的系统
class Mysystem {
public:virtual void run() {cout << "系统启动..." << endl;}
};//必须有权限验证,不是所有人都能来启动我的启动,必须提供用户名和密码int main() {//这样不行。是个人都能启动Mysystem* system = new Mysystem;system -> run();return 0;
}
增加代理模式
#include
using namespace std;//提供一种代理来控制对其他对象的访问
class AbstraactCommonInterface {
public:virtual void run() = 0;};//我已经写好的系统
class Mysystem :public AbstraactCommonInterface{
public:virtual void run() {cout << "系统启动..." << endl;}
};//必须有权限验证,不是所有人都能来启动我的启动,必须提供用户名和密码
class MysystemProxy :public AbstraactCommonInterface {
public:MysystemProxy(string username,string password) {this->mUsername = username;this->mPassword = mPassword;}bool checkUsernameAndPassword() {if (mUsername == "admin"&&mPassword == "admin") {return true;}return false;}virtual void run() {if (checkUsernameAndPassword()) {cout << "用户名和密码正确,验证通过..." << endl;this->pSystem->run();}else {cout << "用户名或密码错误,权限不足...." << endl;}}~MysystemProxy() {if (pSystem != NULL) {delete pSystem;}}
public:Mysystem* pSystem;string mUsername;string mPassword;
};int main() {
#if 0//这样不行。是个人都能启动Mysystem* system = new Mysystem;system -> run();
#endif//调用代理模式MysystemProxy* proxy = new MysystemProxy("root","admin");proxy->run();return 0;
}
通过一种对客户端透明的方式,扩展对象功能
具体操作是,功能放到单独的类中,客户端可以选择、排序等装饰对象。
类别 | 描述 |
适用场景 |
|
优点 |
|
缺点 |
|
#include
using namespace std;//一般情况下,用继承实现类的功能拓展
//装饰模式 可以动态给一个类增加功能//抽象英雄
class AbstractHero {
public:virtual void ShowStatus() = 0;
public:int mHp;int mMp;int mAt;int mDf;
};//具体英雄
class HeroA :public AbstractHero {
public:HeroA() {mHp = 0;mMp = 0;mAt = 0;mDf = 0;}virtual void ShowStatus() {cout << "血量:" << mHp << endl;cout << "魔法:" << mMp << endl;cout << "攻击:" << mAt << endl;cout << "防御:" << mDf << endl;}
};//英雄穿上某个装饰物 那么他还是个英雄
//装饰物
class AbstractEquipmet : public AbstractHero {
public:AbstractEquipmet(AbstractHero* hero) {this->pHero = hero;}virtual void ShowStatus() = 0;
public:AbstractHero* pHero;};//狂徒
class KuangtuEquipment :public AbstractEquipmet {
public:KuangtuEquipment(AbstractHero* hero) :AbstractEquipmet(hero) {}//增加额外的功能void AddKuangtu() {cout << "英雄穿上狂徒之后..." << endl;this->mHp = this->pHero->mHp;this->mMp = this->pHero->mMp;this->mAt = this->pHero->mAt;this->mDf = this->pHero->mDf + 30;delete this->pHero;}virtual void ShowStatus() {AddKuangtu();cout << "血量:" << mHp << endl;cout << "魔法:" << mMp << endl;cout << "攻击:" << mAt << endl;cout << "防御:" << mDf << endl;}
};//无尽
class Wujing : public AbstractEquipmet {
public:Wujing(AbstractHero* hero) :AbstractEquipmet(hero) {}//增加额外的功能void AddWujing() {cout << "英雄穿上无尽之后..." << endl;this->mHp = this->pHero->mHp;this->mMp = this->pHero->mMp;this->mAt = this->pHero->mAt + 80;this->mDf = this->pHero->mDf;delete this->pHero;}virtual void ShowStatus() {AddWujing();cout << "血量:" << mHp << endl;cout << "魔法:" << mMp << endl;cout << "攻击:" << mAt << endl;cout << "防御:" << mDf << endl;}
};int main() {AbstractHero* hero = new HeroA;hero->ShowStatus();cout << "----------------------------" << endl;//给裸奔的英雄穿上衣服后hero = new KuangtuEquipment(hero);hero->ShowStatus();cout << "----------------------------" << endl;//装备武器hero = new Wujing(hero);hero->ShowStatus();return 0;
}
两个子系统,如果都初始化,传统需要一个一个new一下,现在提供一个类,在这个类里面做完初始化工作。
外观模式就是将复杂的子类系统抽象到同一个的接口进行管理,外界只需要通过此接口与子类系统进行交互,而不必要直接与复杂的子类系统进行交互
类别 | 描述 |
适用场景 |
|
优点 |
|
缺点 |
|
#include
using namespace std;//电视机
class Televison {
public:void On() {cout << "电视机打开..." << endl;}void Off() {cout << "电视机关闭" << endl;}
};
//灯
class Light {
public:void On() {cout << "灯打开..." << endl;}void Off() {cout << "灯关闭" << endl;}
};
//音箱
class Audio {
public:void On() {cout << "音箱打开..." << endl;}void Off() {cout << "音箱关闭" << endl;}
};
//麦克风
class Microphone {
public:void On() {cout << "麦克风打开..." << endl;}void Off() {cout << "麦克风关闭" << endl;}
};
//DVD
class DVDPlayer {
public:void On() {cout << "DVD播放器打开..." << endl;}void Off() {cout << "DVD播放器关闭" << endl;}
};
//游戏机
class Gamemachine {
public:void On() {cout << "游戏机打开..." << endl;}void Off() {cout << "游戏机关闭" << endl;}
};//KTV模式
class KTVModel {
public:KTVModel() {pTv = new Televison;pLight = new Light;pAudio = new Audio;pMicrophone = new Microphone;pDVD = new DVDPlayer;}void OnKtv() {pTv->On();pLight->Off();pAudio->On();pMicrophone->On();pDVD->On();}void OffKtv() {pTv->Off();pLight->On();pAudio->Off();pMicrophone->Off();pDVD->Off();}~KTVModel() {delete pTv;delete pLight;delete pAudio;delete pMicrophone;delete pDVD;}public:Televison* pTv;Light* pLight;Audio* pAudio;Microphone* pMicrophone;DVDPlayer* pDVD;
};int main() {KTVModel* ktv = new KTVModel;ktv->OnKtv();return 0;
}
使得原本由于接口不兼容而不能一起工作的那些类可以一起工作
类别 | 描述 |
适用场景 |
|
优点 |
|
缺点 |
|
#include
#include
#include
using namespace std;//适配器模式 就是将已经写好的接口,但是这个接口不符合需求
//将写好的接口转换成目标接口//这函数我已经写好
struct Myprint{void operator()(int v1,int v2) {cout << v1 + v2 << endl;}
};//定义目标接口 我要是配偶 适配成什么样的,
//要适配成只能传一个参数的,适配for_each第三个参数的适用
class Target {
public:virtual void operator()(int v) = 0;};//写适配器
class Adapater :public Target {
public:Adapater(int param) {this->param = param;}virtual void operator() (int v) {print(v,param);}
public:Myprint print;int param;
};//MyBind2nd,原来param固定的10,现在提供一个方法改
Adapater MyBind2nd(int v) {return Adapater(v);
}int main(void) {vector v;for (int i = 0; i < 10; i++) {v.push_back(i);}//适配器模式的运用//for_each()的第三个参数是个带一个参数的函数,但是Myprint需要两个参数for_each(v.begin(),v.end(), MyBind2nd(10));return 0;
}