1. 代理模式
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
1.1 代理模式基本理论
1.2代理模式案例
subject(抽象主题角色):真实主题与代理主题的共同接口。
RealSubject(真实主题角色)∶定义了代理角色所代表的真实对象。
Proxy(代理主题角色):含有对真实主题角色的引用,代理角色通常在将客户端调用传递给真实主题对象之前或者之后执行某些操作,而不是单纯返回真实的对象。
代码示例:
#include <iostream>
using namespace std;
//提供一种代理来控制对其他对象的访问
class AbstractCommonInterface
{
public:
virtual void run() = 0;
};
//我已经写好的系统
class MySystem:public AbstractCommonInterface
{
public:
virtual void run()
{
cout << "系统启动..." << endl;
}
};
//必须要有权限验证,提供同户名和密码
class MySystemProxy :public AbstractCommonInterface
{
public:
MySystemProxy(string username, string password)
{
this->mUsername = username;
this->mPassword = password;
pSystem = new MySystem;
}
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;
};
void test08()
{
MySystemProxy* proxy = new MySystemProxy("root", "admin");
proxy->run();
}
int main()
{
test08();
return 0;
}
2. 外观模式
外观模式就是将复杂的子类系统抽象到同一个的接口进行管理,外界只需要通过此接口与子类系统进行交互,而不必要直接与复杂的子类系统进行交互
2.1 外观模式基本理论
根据迪米特法则,如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。
Facade模式也叫外观模式,是由GoF提出的23种设计模式中的一种。Facade模式为一组具有类似功能的类群,比如类库,子系统等等,提供一个一致的简单的界面。这个一致的简单的界面被称作facade。
2.2 外观模式案例
根据类图,实现家庭影院外观模式应用。
实现KTV模式∶电视打开,灯关掉,音响打开,麦克风打开,dvd打开。实现游戏模式:电视打开,音响打开,游戏机打开。
代码示例:
#include <iostream>
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;
};
void test09()
{
KTVModel* ktv = new KTVModel;
ktv->OnKtv();
}
int main()
{
test09();
return 0;
}
3. 适配器模式
3.1 适配器模式基本理论
将一个类的接口转换成客户希望的另外一个接口。使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
3.2 适配器模式案例
代码示例:
#include <iostream>
#include<vector>
#include<algorithm>
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()
{
vector<int> 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;
}
4. 装饰器模式
4.1 装饰器模式理论
装饰模式又叫包装模式,通过一种对客户端透明的方式来扩展对象功能,是继承关系的一种替代。
装饰模式就是把要附加的功能分别放在单独的类中,并让这个类包含它要装饰的对象,当需要执行时,客户端就可以有选择的、按顺序的使用装饰功能包装对象。
4.2 装饰器模式案例
代码示例:
#include <iostream>
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;
}
};
void test15()
{
AbstractHero* hero = new HeroA;
hero->ShowStatus();
cout << "----------------------------" << endl;
//给裸奔的英雄穿上衣服后
hero = new KuangtuEquipment(hero);
hero->ShowStatus();
cout << "----------------------------" << endl;
//装备武器
hero = new Wujing(hero);
hero->ShowStatus();
}
int main()
{
test15();
return 0;
}