• 常见的结构型设计模式


    设计模式(二)

    常见的结构型模式

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

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

    #include 
    #include 
    /*
    	提供一种代理方法来控制对其他对象的访问
    */
    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 , 开启音响 。 灯光模式: 开启电视 , 开启灯光,开启麦克风。

    具体实现

    #include 
    
    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),转换成我们想要得目标接口。

    #include 
    #include 
    
    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.装饰器模式: 动态的给一个类添加新的功能.

    #include 
    
    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;
    }
    

    效果:

    在这里插入图片描述

  • 相关阅读:
    golang的实用工具
    Spring Security的使用
    docker 部署问题集锦
    Git【入门】从安装到会用(千字总结●超详细)
    beego---ORM相关操作
    文本相似度算法对比分析,短文本相似度主流算法
    AspNetCoreRateLimit应用于MVC项目求助
    Rest风格操作
    艾美捷Enzo人 IgG1 同种型对照化学参数及文献参考
    C++算法竞赛常用编程模板总结
  • 原文地址:https://blog.csdn.net/qq_62989250/article/details/139867099