前言
本文只是记录本人学习设计模式时记录的一些学习笔记,可能不全,但是可以做到一些提醒记忆的作用,如有侵权,联系删改,文章后会贴出学习时参考的链接。此前言适用于本人所写设计模式系列。
结构型模式
描述的是如何组合类和对象以获得更大的结构
7. 代理(Proxy)
为其他对象提供一种代理以控制对这个对象的访问
结构:
- subject(抽象主题角色):
真实主题与代理主题的共同接口。 - Real Subject(真实主题角色):
定义了代理角色所代表的真实对象。 - Proxy(代理主题角色):
含有对真实主题角色的引用,代理角色通常在将客户端调用传递给真是主题对象之前或者之后执行某些操作,而不是单纯返回真实的对象。
示例:
class AbstractCommonInterface{virtual void run() = 0;
};class MySystem : public AbstractCommonInterface{
public:virtual void run(){cout << "system start..." << endl;}virtual ~MySystem(){}
};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 << "success" << endl;this->pSystem->run();}else {cout << "error" << endl;}}~MySystemProxy(){if(pSystem != NULL){delete pSystem;}}
public:MySystem* pSystem;string mUsername;string mPassword;
};
8. 装饰(Decorator )
通过一种对客户端透明的方式来扩展对象功能,是继承关系的一种替代
示例:
- 创建一个抽象类英雄
- 创建一个具体英雄A,继承于抽象英雄
- 创建装饰装备,继承于抽象英雄,使用时,传入被装饰的英雄A,返回穿上装备的英雄A
- 需要装饰什么样的装备,即创建什么样的装备类即可
class AbstractHero{
public:virtual void ShowStatus() = 0;virtual ~AbstractHero(){}
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 AbstractEquipment : public AbstractHero{
public:AbstractEquipment(AbstractHero* hero){this->pHero = hero;}virtual void ShowStatus(){}
public:AbstractHero* pHero;
};
class KuangtuEquipment : public AbstractEquipment{
public:KuangtuEquipment(AbstractHero* hero) :AbstractEquipment(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 WUjinKnife : public AbstractEquipment{
public:WUjinKnife(AbstractHero* hero) :AbstractEquipment(hero){}void AddWUjinKnife(){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(){AddWUjinKnife();cout << "血量:" << mHp << endl;cout << "魔法:" << mMp << endl;cout << "攻击:" << mAt << endl;cout << "防御:" << mDf << endl;}
};
9. 外观(Facade)
将复杂的子类系统抽象到同一个的接口进行管理
结构:
- Facade
为调用方, 定义简单的调用接口。 - Clients
调用者。通过Facade接口调用提供某功能的内部类群。 - Packages
功能提供者。指提供功能的类群(模块或子系统)
示例:
为子系统中统一一套接口,让子系统更加容易使用
class TV{
public:void On(){cout << "TV On..." << endl;}void Off(){cout << "TV Off..." << endl;}
};
class Light{
public:void On(){cout << "Light On..." << endl;}void Off(){cout << "Light Off..." << endl;}
};
class Audio{
public:void On(){cout << "Audio On..." << endl;}void Off(){cout << "Audio Off..." << endl;}
};
class Microphone{
public:void On(){cout << "Microphone On..." << endl;}void Off(){cout << "Microphone Off..." << endl;}
};
class DVDPlayer{
public:void On(){cout << "DVDPlayer On..." << endl;}void Off(){cout << "DVDPlayer Off..." << endl;}
};
class Gamemachine{
public:void On(){cout << "Gamemachine On..." << endl;}void Off(){cout << "Gamemachine Off..." << endl;}
};
class KTVMode{
public:KTVMode(){pTV = new TV;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();}~KTVMode(){delete pTV;delete pLight;delete pAudio;delete pMicrophone;delete pDvd;}
public:TV* pTV;Light* pLight;Audio* pAudio;Microphone* pMicrophone;DVDPlayer* pDvd;
};class GameMode{
//
};
10. 适配器(Adapter)
将一个类的接口转换成客户希望的另一个接口,使得原本由于接口不兼容而不能一起工作的类可以一起工作
示例:
MyPrint接口需要v1,v2两个参数,for_each只返回一个参数,即需要将MyPrint适配成for_each能够使用.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct MyPrint
{void operator()(int v1,int v2){cout << v1 + v2 << endl;}
};
class Target
{
public:virtual void operator()(int v) = 0;
};
class Adapter : public Target
{
public:Adapter(int param){this->param = param;}virtual void operator()(int v){print(v,param);}
public:MyPrint print;int param;
};
int main()
{vector<int> v;for(int i = 0; i < 10; i++){v.push_back(i);}for_each(v.begin(), v.end(),Adapter(10));return 0;
}
11. 桥接(Bridge )
将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。
结构:
- Client
Bridge模式的使用者 - Abstraction
抽象类接口(接口或抽象类)维护对行为实现(Implementor)的引用 - Refined Abstraction
Abstraction子类 - Implementor
行为实现类接口 (Abstraction接口定义了基于Implementor接口的更高层次的操作) - Concrete Implementor
Implementor子类
示例:
class Engine
{
public:virtual void InstallEngine() = 0;};
class E4400cc : public Engine
{
public:virtual void InstallEngine(){cout << "4400cc 安装完毕" << endl;}
};class E4500cc : public Engine
{
public:virtual void InstallEngine(){cout << "4500cc 安装完毕" << endl;}
};class Car
{
public:Car(Engine *engine){this->m_engine = engine;}virtual void installEngine() = 0;
protected:Engine *m_engine;
};class BMW5 : public Car
{
public:BMW5(Engine *engine) : Car(engine){}virtual void installEngine(){cout << "BWM5"<< endl;m_engine->InstallEngine();}
};class BMW8 : public Car
{
public:BMW8(Engine *engine) : Car(engine){}virtual void installEngine(){m_engine->InstallEngine();}
};
12. 组合(Composite)
通过递归手段来构造树形的对象结构,并可以通过一个对象来访问整个对象树。
结构:
- Component (树形结构的节点抽象)
- 为所有的对象定义统一的接口(公共属性,行为等的定义)
- 提供管理子节点对象的接口方法
- [可选]提供管理父节点对象的接口方法 - Leaf (树形结构的叶节点)
- Component的实现子类
- Composite(树形结构的枝节点)
- Component的实现子类
示例:
class IFile
{
public:virtual void display() = 0;virtual int add(IFile *ifile) = 0;virtual int remove(IFile *ifile) = 0;virtual list<IFile *>* getChild() = 0;
};
class File : public IFile
{
public:File(string name){this->m_name = name;}virtual void display(){cout << m_name << endl;}virtual int add(IFile *ifile){return -1;}virtual int remove(IFile *ifile){return -1;}virtual list<IFile *>* getChild(){return NULL;}
private:string m_name;
};class Dir : public IFile
{
public:Dir(string name){this->m_name = name;m_list = new list<IFile *>;m_list->clear();}virtual void display(){cout << m_name << endl;}virtual int add(IFile *ifile){m_list->push_back(ifile);return 0;}virtual int remove(IFile *ifile){m_list->remove(ifile);return 0;}virtual list<IFile *>* getChild(){return m_list;}
private:string m_name;list<IFile *> *m_list;
};void showTree(IFile *dir, int lever)
{dir->display();list<IFile *> *mylist = dir->getChild();if(mylist != NULL){for(list<IFile *>::iterator it = mylist->begin(); it != mylist->end(); it++){for(int i = 0; i <= lever; i++){cout << "\t";}if((*it)->getChild() != NULL){cout << "==>";showTree(*it, lever+1);}else{(*it)->display();}}}
}
13. 享元(Flyweight)
通过与其他类似对象共享数据来减少内存占用
结构:
- 抽象享元角色:
所有具体享元类的父类,规定一些需要实现的公共接口。 - 具体享元角色:
抽象享元角色的具体实现类,并实现了抽象享元角色规定的方法。 - 享元工厂角色:
负责创建和管理享元角色。
示例:
class Person
{
public:Person(string name, int age){this->m_name = name;this->m_age = age;}virtual ~Person(){}virtual void printT() = 0;
protected:string m_name;int m_age;
};
class Teacher : public Person
{
public:Teacher(string name, int age, string id):Person(name, age){this->m_id = id;}void printT(){cout << "name:" << m_name << "\tage:" << m_age << "\tid:" << m_id << endl;}
private:string m_id;
};
class FlyWeightTeacherFactory
{
public:FlyWeightTeacherFactory(){map1.clear();}~FlyWeightTeacherFactory(){while (!map1.empty()) {Person *tmp = NULL;map<string, Person*>::iterator it= map1.begin();tmp = it->second;map1.erase(it);delete tmp;}}Person* GetTeacher(string id){Person *tmp = NULL;map<string, Person*>::iterator it;it = map1.find(id);if(it == map1.end()){string tmpname = "";int tmpage;cout << "\n请输入老师名字:";cin >> tmpname;cout << "\n请输入老师年龄:";cin >> tmpage;tmp = new Teacher(tmpname, tmpage, id);map1.insert(pair<string, Person*>(id, tmp));}else{tmp = it->second;}return tmp;}
private:map<string, Person*> map1;
};
参考
- 黑马程序员C++入门视频教程(完整版)后记提高
- 【设计模式】C语言与C++开发基础
- 结构型模式
- 23种经典设计模式(附c++实现代码) | 王竹兴 |