[架构设计] 结构型模型
目录
一、代理模式
二、装饰模式
三、外观模式
四、适配器模式
一、代理模式
通过一个代理类,来控制对这个对象的访问。
类别 | 描述 |
适用场景 |
|
优点 |
|
缺点 |
|
无代理模式,人人可具备权限
#include <iostream>
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 <iostream>
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 <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;
}
};
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 <bits/stdc++.h>
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 <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(void) {
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;
}