设计模式(六)

设计模式(六)

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

 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. 简化对象通信:同事对象不需要知道其他同事对象的存在或如何与它们通信。它们只需要知道如何与中介者通信

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/906953.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

正反向滤波的简述和MATLAB代码

文章目录 MATLAB 例程:卡尔曼滤波与反向滤波运行结果代码说明总结P.S. 相关公式1. 正向滤波(Forward Filtering)2. 反向滤波(Backward Filtering)3. 总结以下是一个简单的MATLAB例程,演示如何使用卡尔曼滤波进行状态估计,包括正向滤波和反向滤波的实现。这个例程模拟了一…

Django目录结构最佳实践

Django项目目录结构 项目目录结构配置文件引用修改创建自定义子应用方法修改自定义注册目录从apps目录开始 项目目录结构 └── backend # 后端项目目录&#xff08;项目名称&#xff09;├── __init__.py├── logs # 项目日志目录├── manage.py #…

KVM 使用主机 GPU

KVM 如何使用主机的 GPU&#xff0c;首先安装 KVM。 配置Grub vi /etc//etc/default/grub GRUB_CMDLINE_LINUX"amd_iommuon iommupt videoefifb:off vfio_pci.ids10de:1e07,10de:10f7,10de:1ad6,10de:1ad7"查看主机显卡信息 lspci -nnk | grep -A 3 VGA 找到GP…

b站小土堆PyTorch视频学习笔记(二)

Dataloader:提供不同类型的数据集&#xff1b;为后面的网络提供不同的数据形式 Dataset&#xff1a;提供一种方式去获取数据及其label&#xff08;标签&#xff09; 主要实现以下两个功能&#xff1a; {如何获取每一个数据及其lable&#xff1b;告诉我们总共有多少数据} fr…

nginx的proxy_next_upstream使用中的一个坑

今天线上系统出了点问题&#xff0c;机房的电信出口突然不通了&#xff0c;原本以为能自动切换的nginx配置&#xff0c;居然没有生效&#xff0c;导致了业务告警&#xff0c;手工紧急处理了才解决了。 当时的设想是&#xff0c;如果这个服务的访问&#xff0c;出现了500或者超…

【Git】SSH密钥

目录 1 前言2 SSH密钥2.1 生成密钥2.2 查看密钥2.3 关联Git服务器 3 小结 1 前言 许多Git服务器都使用SSH公钥进行认证&#xff0c;为了向Git服务器提供SSH公钥&#xff0c;如果某系统用户尚未拥有密钥&#xff0c;必须事先为其生成一份。 2 SSH密钥 2.1 生成密钥 在Window…

【Seed-Labs】SQL Injection Attack Lab

Overview SQL 注入是一种代码注入技术&#xff0c;利用的是网络应用程序与数据库服务器之间接口的漏洞。当用户输入的信息在发送到后端数据库服务器之前没有在网络应用程序中进行正确检查时&#xff0c;就会出现这种漏洞。 许多网络应用程序从用户那里获取输入&#xff0c;然…

ClkLog企业版(CDP)预售开启,更有鸿蒙SDK前来助力

新版本发布 ClkLog在上线近1年后&#xff0c;获得了客户的一致肯定与好评&#xff0c;并收到了不少客户对功能需求的反馈。根据客户的反馈&#xff0c;我们在今年三季度对ClkLog的版本进行了重新的规划与调整&#xff0c;简化了原有的版本类型&#xff0c;方便客户进行选择。 与…

T矩阵其实就是pauli基的乘,S矩阵中hv是体散射分量

注意什么是面散射&#xff0c;二次散射和体散射。 ShhSvv表示单次散射的电压&#xff0c;|ShhSvv|^2是功率

群控系统服务端开发模式-应用开发-上传配置功能开发

下面直接进入上传配置功能开发&#xff0c;废话不多说。 一、创建表 1、语句 CREATE TABLE cluster_control.nc_param_upload (id int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 编号,upload_type tinyint(1) UNSIGNED NOT NULL COMMENT 上传类型 1&#xff1a;本站 2&a…

HarmonyOS NEXT 应用开发实战(九、知乎日报项目详情页实现详细介绍)

在本篇博文中&#xff0c;我们将探讨如何使用 HarmonyOS Next 框架开发一个知乎日报的详情页&#xff0c;逐步介绍所用到的组件及代码实现。知乎日报是个小巧完整的小项目&#xff0c;这是一个循序渐进的过程&#xff0c;适合初学者和有一定开发经验的工程师参考。 1. 项目背景…

数据结构之链式结构二叉树的实现(初级版)

本文内容将主会多次用到函数递归知识&#xff01;&#xff01;&#xff01; 本节内容需要借助画图才能更好理解&#xff01;&#xff01;&#xff01; 和往常一样&#xff0c;还是创建三个文件 这是tree.h #pragma once #include<stdio.h> #include<stdlib.h> …

数据结构(Java)—— 认识泛型

1. 包装类 在学习泛型前我们需要先了解一下包装类 在 Java 中&#xff0c;由于基本类型不是继承自 Object &#xff0c;为了在泛型代码中可以支持基本类型&#xff0c; Java 给每个基本类型都对应了一个包装类型。 1.1 基本数据类型和对应的包装类 基本数据类型包装类byteByt…

LSTM模型改进实现多步预测未来30天销售额

项目源码获取方式见文章末尾&#xff01; 600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【BiLSTM模型实现电力数据预测】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模型实…

使用带有令牌认证的 Jupyter Notebook 服务器

当你不想在默认浏览器打开Jupyter Notebook,但是在其他浏览器打开http://localhost:8890/lab或者http://localhost:8889/tree&#xff0c;却显示 Token authentication is enabled&#xff0c;如下图 可以按以下步骤操作&#xff1a; 获取令牌&#xff1a;在启动 Jupyter Note…

软考(中级-软件设计师)数据库篇(1101)

第6章 数据库系统基础知识 一、基本概念 1、数据库 数据库&#xff08;Database &#xff0c;DB&#xff09;是指长期存储在计算机内的、有组织的、可共享的数据集合。数据库中的数据按一定的数据模型组织、描述和存储&#xff0c;具有较小的冗余度、较高的数据独立性和扩展…

【java】java的基本程序设计结构06-运算符

运算符 一、分类 算术运算符关系运算符位运算符逻辑运算符赋值运算符其他运算符 1.1 算术运算符 操作符描述例子加法 - 相加运算符两侧的值A B 等于 30-减法 - 左操作数减去右操作数A – B 等于 -10*乘法 - 相乘操作符两侧的值A * B等于200/除法 - 左操作数除以右操作数B /…

躺平成长-代码开发(07)-利用kimi帮助自己写代码

开源竞争&#xff1a; 开源竞争&#xff08;当你无法彻底掌握技术的时候&#xff0c;就去开源这个技术&#xff0c;让更多人了解这个技术&#xff0c;随着越来越多的人了解这个技术&#xff0c;就会培养出更多的技术依赖&#xff0c;让更多的人帮助你们完善你的技术依赖&#x…

基于javaweb(springboot+mybatis)网站建设服务管理系统设计和实现以及文档报告设计

基于javaweb(springbootmybatis)网站建设服务管理系统设计和实现以及文档报告设计 &#x1f345; 作者主页 网顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取…

时间序列预测(十)——长短期记忆网络(LSTM)

目录 一、LSTM结构 二、LSTM 核心思想 三、LSTM分步演练 &#xff08;一&#xff09;初始化 1、权重和偏置初始化 2、初始细胞状态和隐藏状态初始化 &#xff08;二&#xff09;前向传播 1、遗忘门计算&#xff08;决定从上一时刻隐状态中丢弃多少信息&#xff09; 2、…