常见的结构型设计模式

设计模式(二)

常见的结构型模式

1.代理模式: 提供一种代理方法 ,来控制对其他对象的访问。在有些情况下,一个对象不能或者不适合直接访问另一个对象,而代理对象可以在这两个类之间起一个中介的作用。

举例:我们要启动一个系统 , 但是并不是所有的人都有权限来启动系统 ,所以我们需要一个代理方法来管理。

cpp 复制代码
#include <iostream>
#include <string>
/*
	提供一种代理方法来控制对其他对象的访问
*/
class System {
public:
	virtual void run() = 0;

	virtual ~System() { }
};

class MySystem :public System {
public:
	MySystem( ) {  }
	virtual ~MySystem() {  }

	virtual void run() {
		std::cout << "系统启动" << std::endl;
	}
};

// 代理类 ( 系统启动需要验证用户名和密码 )
class myProxy:public System {
public:
	myProxy(std::string userName ,std::string userPassword):userName_( userName ),userPassword_( userPassword ) { 
		my_system_ = new MySystem;
	}
	virtual ~myProxy( ) { 
		if (my_system_) {
			delete my_system_;
			my_system_ = nullptr;
		}
	}

	virtual void run() {
		if (checkUserNameAndUserPassword()) {
			std::cout << "用户名和密码正确,正在启动系统......." << std::endl;
			my_system_ -> run();
		}
		else {
			std::cout << "用户名和密码错误,权限不足......." << std::endl;
		}
	}

	bool checkUserNameAndUserPassword() {
		if (userName_ == "R" && userPassword_ == "R") {
			return true;
		}
		return false;
	}

private:
	MySystem* my_system_ ;
	std::string userName_;
	std::string userPassword_;
};


int main() {
	// 我们的代理类
	myProxy* proxy = new myProxy("R", "R");
	// 通过代理类来启动系统
    proxy->run();

	system("pause");

	return 0;
}

2.外观模式: 将一些复杂的子系统全都抽象到同一个接口进行管理 , 外界只需要通过这个接口,就可以和子系统进行交互,而不需要直接和这些复杂的子系统进行交互。

案例:假设KTV有两种模式,游戏模式:开启wifi , 开启音响 。 灯光模式: 开启电视 , 开启灯光,开启麦克风。

具体实现

cpp 复制代码
#include <iostream>

class Wifi {
public:
	Wifi() {
		std::cout << "wifi开启" << std::endl;
	}
	~Wifi() { }
};

class Sound {
public:
	Sound() { 
		std::cout << "音响开启"<<std::endl;
	}
	~Sound() { }
};

class Tv {
public:
	Tv() {
		std::cout << "电视开启" << std::endl;
	}
	~Tv() { }
};

class Night {
public:
	Night() { 
		std::cout << "开启灯光" << std::endl;
	}
	~Night() { }
};

class Microphone {
public:
	Microphone() {
		std::cout << "开启麦克风" << std::endl;
	}
	~Microphone() { }
};

class FacedPattern {
public:
	FacedPattern( ) {  }
	void openGamePattern() {
		wifi_ = new Wifi;
		sound_ = new Sound;
	}
	void openNightPattern() {
		microphone_ = new Microphone;
		night_ = new Night;
		tv_ = new Tv;
	}

	~FacedPattern() {
		if (wifi_) {
			delete wifi_;
			wifi_ = nullptr;
		}
		if (night_) {
			delete night_;
			night_ = nullptr;
		}
		if (tv_) {
			delete  tv_;
			tv_ = nullptr;
		}
		if (microphone_) {
			delete  microphone_;
			microphone_ = NULL;
		}
		if (sound_) {
			delete sound_;
			sound_ = nullptr;
		}
	}
private:
	Wifi* wifi_; 
	Night *night_;
	Tv* tv_;
	Microphone* microphone_;
	Sound* sound_;
};

int main() {
	FacedPattern facePattern;
	facePattern.openGamePattern();
	facePattern.openNightPattern();

	return 0;
}

3.适配器模式: 将已经写好得接口(但是这个接口是不符合需求de),转换成我们想要得目标接口。

cpp 复制代码
#include <iostream>
#include <string>

using namespace std;

// 旧接口
class OldPriter {
public:
	OldPriter() { }
	void print(std::string text) {
		std::cout << "oldPriter: " << text << std::endl;
	}
};

// 新接口
class NewPriter {
public:
	NewPriter() { }
	void print(std::string text) {
		std::cout << "newPriter: " << text << std::endl;
	}
};

// 适配器接口
class Adapter:public OldPriter {
public:
	void print(std::string text) {
		newPriter.print(text);
	}
private:
	NewPriter newPriter;
};

4.装饰器模式: 动态的给一个类添加新的功能.

cpp 复制代码
#include <iostream>

using namespace std;

/*
	一个英雄的属性 :  防御、攻击力
	装饰一个反甲 :   防御力 + 30
	装饰一把无尽之刃 : 攻击力 + 60
*/

// 英雄的抽象类
class AbstractHero {
public:
	virtual ~AbstractHero() { }
	virtual void showHeroState() = 0;
public:
	int defense_ ;   // 防御
	int attack_ ;	// 工具
};

// 具体的英雄--->石头人
class Malphite :public AbstractHero {
public:
	Malphite( ){
		// 没购买装备 ,攻击力和防御力都是60
		attack_ = 60;
		defense_ = 60;
	}
	virtual void showHeroState() {
		cout << "初始状态:" << endl;
		cout << "<防御力>" << defense_ << endl;
		cout << "<攻击力>" << attack_ << endl;
	}
	virtual ~Malphite() {  } 
};

// 装饰器抽象类
class AbstractDecoratorPattern :public AbstractHero {
public:
	AbstractDecoratorPattern( AbstractHero* Hero ){
		this->Hero_ = Hero;
	}
	virtual ~AbstractDecoratorPattern( ) {  }

	virtual void showHeroState() { }
public:
	AbstractHero* Hero_;
};

// 给石头人添加一个反甲(  Coelonychia--->反甲 )
class Coelonychia  : public AbstractDecoratorPattern {
public:
	Coelonychia( AbstractHero* Hero ): AbstractDecoratorPattern( Hero ){   }
	virtual ~Coelonychia() { delete this->Hero_; }

	virtual void showHeroState() {
		AddEquip();
		cout << "穿上反甲之后:" << endl;
		cout << "<防御力>" << this->defense_ << endl;
		cout << "<攻击力>" << this->attack_ << endl;
	}
	void AddEquip( ) {
		this->defense_  = this->Hero_->defense_ + 30;
		this->attack_ = this->Hero_->attack_;
	}
};

// 给石头人添加一个无尽之刃(  wujinzhiren--->反甲 )
class WuJinZhiRen : public AbstractDecoratorPattern {
public:
	WuJinZhiRen(AbstractHero* Hero) : AbstractDecoratorPattern( Hero ) {  }
	virtual ~WuJinZhiRen() { delete this->Hero_;  }

	virtual void showHeroState() {
		AddEquip();
		cout << "购买无尽之刃后:" << endl;
		cout << "<防御力>" << this->defense_ << endl;
		cout << "<攻击力>" << this->attack_ << endl;
		
	}
	void AddEquip() {
		this->attack_ = this->Hero_->attack_ + 60;
		this->defense_ = this->Hero_->defense_;
	}
};

void test() {
	AbstractHero* Hero = new Malphite;   // 一个石头人对象
	Hero->showHeroState();
	cout << "-----------" << endl;
	Hero = new Coelonychia(Hero);
	Hero->showHeroState();
	cout << "-----------" << endl;
	Hero = new WuJinZhiRen(Hero);
	Hero->showHeroState();	
}

int main( ) {
	
	test();

	return 0;
}

效果:

相关推荐
唐诺36 分钟前
几种广泛使用的 C++ 编译器
c++·编译器
冷眼看人间恩怨2 小时前
【Qt笔记】QDockWidget控件详解
c++·笔记·qt·qdockwidget
红龙创客2 小时前
某狐畅游24校招-C++开发岗笔试(单选题)
开发语言·c++
Lenyiin2 小时前
第146场双周赛:统计符合条件长度为3的子数组数目、统计异或值为给定值的路径数目、判断网格图能否被切割成块、唯一中间众数子序列 Ⅰ
c++·算法·leetcode·周赛·lenyiin
yuanbenshidiaos3 小时前
c++---------数据类型
java·jvm·c++
十年一梦实验室4 小时前
【C++】sophus : sim_details.hpp 实现了矩阵函数 W、其导数,以及其逆 (十七)
开发语言·c++·线性代数·矩阵
taoyong0014 小时前
代码随想录算法训练营第十一天-239.滑动窗口最大值
c++·算法
这是我584 小时前
C++打小怪游戏
c++·其他·游戏·visual studio·小怪·大型·怪物
fpcc4 小时前
跟我学c++中级篇——C++中的缓存利用
c++·缓存
呆萌很4 小时前
C++ 集合 list 使用
c++