设计模式(六)

news/2024/11/1 14:32:50/

设计模式(六)

组件构建过程中,某些接口之间的依赖常常会带来很多问题,甚至根本无法实现。采用添加一层间接稳定接口,来隔离本来互相紧密关联的接口是一种常见的解决方案

 1.门面(Facade):门面类知道哪些子系统负责处理哪些请求,将客户端的请求代理给适当的子系统对象2.子系统(Subsystem):实现子系统的功能。子系统并不意识到门面,它们接受请求并处理,通常是由多个类组成的复杂系统3.客户端(Client):使用门面来与子系统进行交互

eg:

 // 子系统类class Subsystem1 {public:void operation1() {// ...}};class Subsystem2 {public:void operation2() {// ...}};class Subsystem3 {public:void operation3() {// ...}};// 门面类class Facade {private:Subsystem1* subsystem1;Subsystem2* subsystem2;Subsystem3* subsystem3;public:Facade() {subsystem1 = new Subsystem1();subsystem2 = new Subsystem2();subsystem3 = new Subsystem3();}void operation() {subsystem1->operation1();subsystem2->operation2();subsystem3->operation3();}~Facade() {delete subsystem1;delete subsystem2;delete subsystem3;}};// 客户端代码int main() {Facade* facade = new Facade();facade->operation();delete facade;return 0;}

代理模式

允许我们为其他对象提供一种代理以控制对这个对象的访问。代理模式的关键是提供一个替身或占位符,以控制对原始对象的访问

不改变原始对象代码的情况下,通过引入代理对象来间接访问原始对象,以添加额外的功能,如访问控制、日志记录、缓存等

1.抽象主题(Subject):定义了RealSubject和Proxy的共用接口,这样就可以使用代理来代替真实对象。
2.真实主题(RealSubject):定义了代理所代表的真实对象,代理会控制对它的访问。
3.代理(Proxy):保存一个引用使得代理可以访问真实对象,并提供一个与真实主题相同的接口。代理可以附加一些额外的功能,如权限验证、延迟加载等
// 抽象主题
class Image {
public:virtual void display() = 0;
};// 真实主题
class RealImage : public Image {
private:string filename;public:RealImage(string filename) {this->filename = filename;loadFromDisk();}void display() override {cout << "Displaying " << filename << endl;}private:void loadFromDisk() {cout << "Loading " << filename << endl;}
};// 代理
class ProxyImage : public Image {
private:RealImage* realImage;string filename;public:ProxyImage(string filename) {this->filename = filename;}~ProxyImage() {delete realImage;}void display() override {if (realImage == nullptr) {realImage = new RealImage(filename);}realImage->display();}
};// 客户端代码
int main() {Image* image = new ProxyImage("test_image.jpg");// 图像将在第一次显示时加载image->display();cout << "---------------------" << endl;// 图像不会再次从磁盘加载image->display();delete image;return 0;
}
适配器模式

将一个类得接口转换成客户希望得另一个接口,Adapter模式使得原本由于接口不兼容而不能一起工作得那些类可以一起工作

1.目标接口(Target):定义客户端使用的接口,客户端期望与这个接口协同工作。
2.被适配者(Adaptee):一个已经存在的类或对象,其接口与目标接口不兼容。
3.适配器(Adapter):一个中介类,通过继承或组合的方式实现目标接口,并将目标接口的调用转化为被适配者接口的调用

eg:

// 目标接口
class Target {
public:virtual void request() = 0;
};// 被适配者
class Adaptee {
public:void specificRequest() {// 实现特定的功能}
};// 适配器
class Adapter : public Target {
private:Adaptee* adaptee;public:Adapter(Adaptee* adaptee) {this->adaptee = adaptee;}void request() override {// 调用被适配者的方法以实现目标接口adaptee->specificRequest();}
};// 客户端代码
int main() {Adaptee* adaptee = new Adaptee();Target* adapter = new Adapter(adaptee);// 客户端通过目标接口与适配器交互adapter->request();delete adaptee;delete adapter;return 0;
}

将目标接口与被适配者解耦,使得两者可以独立变化,通过引入一个适配器类,可以在不修改现有代码的基础上增加新的接口功能

中介模式

将多个对象间复杂得关系解耦,Mediator模式将多个对象间得控制逻辑进行集中管理,变多个对象互相关联 为多个对象和一个中介者关联,简化了系统得维护,抵御了可能得变化

将原理相互依赖得对象,现在使其分离,然后让所有对象和一个中间对象相互依赖

// 中介者接口
class Mediator {
public:virtual void send(std::string message, Colleague* sender) = 0;
};// 同事接口
class Colleague {
protected:Mediator* mediator;
public:Colleague(Mediator* mediator) {this->mediator = mediator;}
};// 具体的同事类
class ConcreteColleague1 : public Colleague {
public:ConcreteColleague1(Mediator* mediator) : Colleague(mediator) {}void send(std::string message) {mediator->send(message, this);}void notify(std::string message) {std::cout << "Colleague1 gets message: " << message << std::endl;}
};class ConcreteColleague2 : public Colleague {
public:ConcreteColleague2(Mediator* mediator) : Colleague(mediator) {}void send(std::string message) {mediator->send(message, this);}void notify(std::string message) {std::cout << "Colleague2 gets message: " << message << std::endl;}
};// 具体的中介者类
class ConcreteMediator : public Mediator {
private:ConcreteColleague1* colleague1;ConcreteColleague2* colleague2;
public:ConcreteMediator() : colleague1(nullptr), colleague2(nullptr) {}void setColleague1(ConcreteColleague1* colleague) {this->colleague1 = colleague;}void setColleague2(ConcreteColleague2* colleague) {this->colleague2 = colleague;}void send(std::string message, Colleague* sender) override {if (sender == colleague1) {colleague2->notify(message);} else {colleague1->notify(message);}}
};// 客户端代码
int main() {ConcreteMediator mediator;ConcreteColleague1 colleague1(&mediator);ConcreteColleague2 colleague2(&mediator);mediator.setColleague1(&colleague1);mediator.setColleague2(&colleague2);colleague1.send("Hello from Colleague1");colleague2.send("Hello from Colleague2");return 0;
}
  1. 集中控制:所有消息传递的逻辑都集中在ConcreteMediator类中,这使得管理和修改消息传递规则变得更加容易
  2. 简化对象通信:同事对象不需要知道其他同事对象的存在或如何与它们通信。它们只需要知道如何与中介者通信

http://www.ppmy.cn/news/1543606.html

相关文章

InnoDB存储引擎对MVCC实现

MVCC&#xff08;多版本并控制&#xff09; 概念&#xff1a;MVCC 是一种并发控制机制。 作用&#xff1a;多个并发事务同时读写数据库时保持数据的一致性和隔离性 实现&#xff1a;在每个数据行上维护多个版本的数据来实现的。当一个事务要对数据库中的数据进行修改时&…

一种基于机器学习的面向内生安全系统的入侵修复方式

摘要&#xff1a;本文主要是根据上课老师所提供的题目以及平时上课的学习&#xff0c;结合自己的理解按照要求设计的一种基于机器学习等方法的面向内生安全系统的入侵修复方式和系统&#xff0c;虽然大部分只是一种猜想并未实际实现&#xff0c;但是所体现的创新性等也是有可取…

Lua 函数

Lua 函数 Lua 是一种轻量级的编程语言&#xff0c;广泛用于游戏开发、脚本编写和其他应用程序中。在 Lua 中&#xff0c;函数是一等公民&#xff0c;这意味着它们可以被赋值给变量&#xff0c;作为参数传递给其他函数&#xff0c;甚至可以作为其他函数的返回值。本文将详细介绍…

Rust 力扣 - 1423. 可获得的最大点数

文章目录 题目描述题解思路题解代码题解链接 题目描述 题解思路 题目所求结果存在下述等式 可获得的最大点数 所有卡牌的点数之和 - 长度为&#xff08;卡牌数量 - k&#xff09;的窗口的点数之和的最小值 我们遍历长度为&#xff08;卡牌数量 - k&#xff09;的窗口&#…

springboot2.x使用SSE方式代理或者转发其他流式接口

文章目录 1.需求描述2.代码2.1.示例controller2.2.示例service2.3.示例impl 3.测试 1.需求描述 使用SSE的方式主要还是要跟前端建立一个EventSource的链接&#xff0c;有了这个连接&#xff0c;然后往通道里写入数据流&#xff0c;前端自然会拿到流式数据&#xff0c;写啥拿啥…

同城行业交流圈子/交友圈子论坛系统有哪些开源架构与优势解析

开源架构 前端 Vue.js与uni-app框架&#xff1a;前端常采用Vue.js框架&#xff0c;特别是结合uni-app进行跨平台开发。uni-app是一个使用Vue.js开发所有前端应用的框架&#xff0c;支持编译为H5、小程序、App等多个平台&#xff0c;实现代码的一次编写&#xff0c;多端运行。…

【机器学习】有监督学习·由浅入深讲解分类算法·Fisher算法讲解

博主简介&#xff1a;努力学习的22级计算机科学与技术本科生一枚&#x1f338;博主主页&#xff1a; Yaoyao2024往期回顾&#xff1a; 【机器学习】深入浅出讲解贝叶斯分类算法每日一言&#x1f33c;: Rivers know this&#xff1a;There is no hurry. We shall get there. 0、…

单例 C++ 懒汉+恶汉

单例设计模式是一种创建型设计模式&#xff0c;确保一个类只有一个实例&#xff0c;减少了内存的开销&#xff0c;并提供一个全局访问点访问该实例。 私有化构造函数、拷贝构造函数、赋值函数 &#xff0c;定义一个类的私有静态对象成员&#xff0c;定义一个公共的访问该实例静…