02-结构型设计模式(共7种)

1. Adapter(适配器模式)

        适配器模式是一种结构型设计模式,它允许将一个类的接口转换成客户端所期望的另一个接口。这种模式通常用于解决接口不兼容的情况,使得原本由于接口不匹配而无法工作的类可以一起工作。

        在 C++ 中,适配器模式可以通过类适配器对象适配器两种方式来实现。

1.1 类适配器

        使用多重继承实现适配器类,使其既继承目标接口,又继承被适配的类

        以下是模式示例:

#include <iostream>

// 目标接口
class Target {
public:
    virtual void request() = 0;
};

// 被适配的类
class Adaptee {
public:
    void specificRequest() {
        std::cout << "Specific request from Adaptee" << std::endl;
    }
};

// 类适配器,继承目标接口和被适配类
class Adapter : public Target, private Adaptee {
public:
    void request() override {
        specificRequest(); // 调用被适配类的方法
    }
};

int main() {
    Target* target = new Adapter();
    target->request();

    delete target;
    return 0;
}

1.2 对象适配器

        使用对象组合实现适配器类,使其持有被适配的对象实例

        以下是模式示例: 

#include <iostream>

// 目标接口
class Target {
public:
    virtual void request() = 0;
};

// 被适配的类
class Adaptee {
public:
    void specificRequest() {
        std::cout << "Specific request from Adaptee" << std::endl;
    }
};

// 对象适配器,持有被适配类的对象实例
class Adapter : public Target {
private:
    Adaptee* adaptee;

public:
    Adapter(Adaptee* adaptee) : adaptee(adaptee) {}

    void request() override {
        adaptee->specificRequest(); // 调用被适配类的方法
    }
};

int main() {
    Adaptee* adaptee = new Adaptee();
    Target* target = new Adapter(adaptee);
    target->request();

    delete target;
    delete adaptee;
    return 0;
}

        无论是类适配器还是对象适配器,都可以实现将目标接口和被适配类进行适配,使得客户端可以统一调用目标接口的方法,而无需直接与被适配类打交道。

2. Decorator(装饰器模式)

        装饰器模式是一种结构型设计模式,它允许向现有对象添加新功能,同时又不改变其结构。这种模式通过创建包装类(装饰器)来实现,在包装类中包含一个指向被包装对象的引用,并且实现与被包装对象相同的接口

2.1 使用继承实现装饰器模式

        以下是模式示例:

#include <iostream>

// 抽象组件
class Component {
public:
    virtual void operation() = 0;
};

// 具体组件
class ConcreteComponent : public Component {
public:
    void operation() override {
        std::cout << "Concrete Component operation" << std::endl;
    }
};

// 抽象装饰器
class Decorator : public Component {
protected:
    Component* component;

public:
    Decorator(Component* comp) : component(comp) {}

    void operation() override {
        if (component != nullptr) {
            component->operation();
        }
    }
};

// 具体装饰器A
class ConcreteDecoratorA : public Decorator {
public:
    ConcreteDecoratorA(Component* comp) : Decorator(comp) {}

    void operation() override {
        Decorator::operation();
        addBehaviorA();
    }

    void addBehaviorA() {
        std::cout << "Added behavior A" << std::endl;
    }
};

// 具体装饰器B
class ConcreteDecoratorB : public Decorator {
public:
    ConcreteDecoratorB(Component* comp) : Decorator(comp) {}

    void operation() override {
        Decorator::operation();
        addBehaviorB();
    }

    void addBehaviorB() {
        std::cout << "Added behavior B" << std::endl;
    }
};

int main() {
    Component* component = new ConcreteComponent();
    Component* decoratedA = new ConcreteDecoratorA(component);
    Component* decoratedB = new ConcreteDecoratorB(decoratedA);

    decoratedB->operation();

    delete decoratedB;
    delete decoratedA;
    delete component;

    return 0;
}

2.2 使用组合实现装饰器模式

        当使用组合实现装饰器模式时,装饰器类将持有一个对被装饰对象的引用,并在其基础上添加额外的功能

#include <iostream>

// 抽象组件
class Component {
public:
    virtual void operation() = 0;
};

// 具体组件
class ConcreteComponent : public Component {
public:
    void operation() override {
        std::cout << "Concrete Component operation" << std::endl;
    }
};

// 抽象装饰器
class Decorator : public Component {
protected:
    Component* component;

public:
    Decorator(Component* comp) : component(comp) {}

    void operation() override {
        if (component != nullptr) {
            component->operation();
        }
    }
};

// 具体装饰器A
class ConcreteDecoratorA : public Decorator {
public:
    ConcreteDecoratorA(Component* comp) : Decorator(comp) {}

    void operation() override {
        Decorator::operation();
        addBehaviorA();
    }

    void addBehaviorA() {
        std::cout << "Added behavior A" << std::endl;
    }
};

// 具体装饰器B
class ConcreteDecoratorB : public Decorator {
public:
    ConcreteDecoratorB(Component* comp) : Decorator(comp) {}

    void operation() override {
        Decorator::operation();
        addBehaviorB();
    }

    void addBehaviorB() {
        std::cout << "Added behavior B" << std::endl;
    }
};

int main() {
    Component* component = new ConcreteComponent();
    Decorator* decoratedA = new ConcreteDecoratorA(component);
    Decorator* decoratedB = new ConcreteDecoratorB(decoratedA);

    decoratedB->operation();

    delete decoratedB;
    delete decoratedA;
    delete component;

    return 0;
}

 3. Proxy(代理模式)

        代理模式是一种结构型设计模式,它允许通过一个代理对象控制对另一个对象的访问。代理模式可以用于各种场景,例如:远程代理、虚拟代理、保护代理等,以实现对目标对象的访问控制、延迟加载、缓存等功能。

        在 C++ 中,代理模式可以通过以下方式实现:

        ①. 虚拟代理(Virtual Proxy):延迟加载对象,在需要时才真正创建对象。
        ②. 保护代理(Protection Proxy):控制对象的访问权限,提供额外的安全性。
        ③. 远程代理(Remote Proxy):在不同地址空间中代表对象,实现远程通信。

         以下是模式示例:  

#include <iostream>
#include <string>

// 抽象主题
class Subject {
public:
    virtual void request() = 0;
};

// 具体主题
class RealSubject : public Subject {
public:
    void request() override {
        std::cout << "Real Subject request" << std::endl;
    }
};

// 代理类
class Proxy : public Subject {
private:
    RealSubject* realSubject;
    bool initialized;

public:
    Proxy() : realSubject(nullptr), initialized(false) {}

    void request() override {
        if (!initialized) {
            lazyInit();
        }
        realSubject->request();
    }

    void lazyInit() {
        std::cout << "Proxy initializing..." << std::endl;
        realSubject = new RealSubject();
        initialized = true;
    }
};

int main() {
    Proxy proxy;
    proxy.request();

    return 0;
}

        在上面的示例中,Subject 是抽象主题类,定义了对实际主题进行操作的接口。RealSubject 是具体主题类,实现了真正的业务逻辑。Proxy 是代理类,延迟初始化 RealSubject 对象,并在需要时调用其方法

        当运行主函数时,代理对象首先进行了延迟初始化(虚拟代理的特性),然后通过代理对象调用实际主题的方法,实现了对实际主题的代理访问。

4. Composite(组合模式)

        组合模式是一种结构型设计模式,它允许将对象组合成树形结构以表示“部分-整体”的层次关系组合模式使得客户端可以统一处理单个对象和对象组合,从而使得客户端代码更加简单且具有一致性。

        在 C++ 中,组合模式通常涉及以下几个角色:

        ①. Component(组件):是组合中的对象声明接口,在适当的情况下,实现所有类共有接口的缺省行为。可以是抽象类或接口。

        ②. Leaf(叶子节点):是组合中的叶节点对象,它没有子节点。

        ③. Composite(复合节点):是组合中的复合对象,它有子节点。通常实现了在 Component 接口中定义的操作,这些操作可以通过递归调用子节点来实现

        以下是模式示例: 

#include <iostream>
#include <string>
#include <vector>

// 抽象组件类
class Component {
public:
    virtual void operation() const = 0;
};

// 叶子节点类
class Leaf : public Component {
private:
    std::string name;

public:
    Leaf(const std::string& name) : name(name) {}

    void operation() const override {
        std::cout << "Leaf " << name << " operation" << std::endl;
    }
};

// 复合节点类
class Composite : public Component {
private:
    std::vector<Component*> children;

public:
    void add(Component* component) {
        children.push_back(component);
    }

    void remove(Component* component) {
        // 省略移除逻辑
    }

    void operation() const override {
        for (Component* child : children) {
            child->operation();
        }
    }
};

int main() {
    Leaf leafA("A");
    Leaf leafB("B");

    Composite composite;
    composite.add(&leafA);
    composite.add(&leafB);

    composite.operation();

    return 0;
}

        在上述示例中,我们定义了 Component 抽象组件类,Leaf 叶子节点类和 Composite 复合节点类。叶子节点表示组合中的最终节点,而复合节点表示可以包含子节点的节点。在 main 函数中,我们创建了两个叶子节点 leafA 和 leafB,然后将它们添加到了复合节点 composite 中,最后通过复合节点的 operation 方法调用了所有子节点的 operation 方法,实现了对整个组合结构的统一处理。

5. Facade(外观模式)

        外观模式是一种结构型设计模式,它提供了一个统一的接口,用于访问子系统中的一群接口。外观模式定义了一个高层接口,这个接口使得子系统更容易使用。

        在 C++ 中,外观模式通常包括以下几个角色:

        ①. Facade(外观):对客户端提供简单的接口,隐藏了系统的复杂性,提供了对子系统的统一访问接口。

        ②. Subsystems(子系统):包含了一组相关的类和接口,实现了系统的功能。

        以下是模式示例: 

#include <iostream>

// 子系统A
class SubsystemA {
public:
    void operationA() const {
        std::cout << "SubsystemA operation" << std::endl;
    }
};

// 子系统B
class SubsystemB {
public:
    void operationB() const {
        std::cout << "SubsystemB operation" << std::endl;
    }
};

// 子系统C
class SubsystemC {
public:
    void operationC() const {
        std::cout << "SubsystemC operation" << std::endl;
    }
};

// 外观类
class Facade {
private:
    SubsystemA subsystemA;
    SubsystemB subsystemB;
    SubsystemC subsystemC;

public:
    void operation() const {
        subsystemA.operationA();
        subsystemB.operationB();
        subsystemC.operationC();
    }
};

int main() {
    Facade facade;
    facade.operation();

    return 0;
}

6. Bridge(桥接模式)

        桥接模式是一种结构型设计模式,它将抽象部分与其实现部分分离,使它们可以独立变化,从而达到解耦的目的桥接模式通过组合而不是继承的方式来实现这种分离

        在 C++ 中,桥接模式通常涉及以下几个角色:

        ①. Abstraction(抽象类):定义抽象部分的接口,并维护一个对实现部分对象的引用。

        ②. Implementor(实现类接口):定义实现部分的接口,它与抽象部分接口保持一致。

        ③. ConcreteImplementor(具体实现类):实现实现类接口,提供具体的实现。

        ④. RefinedAbstraction(扩充抽象类):扩展抽象部分的接口,通常通过组合的方式来调用实现部分的方法。

        以下是模式示例: 

#include <iostream>

// 实现类接口
class Implementor {
public:
    virtual void operationImpl() const = 0;
};

// 具体实现类A
class ConcreteImplementorA : public Implementor {
public:
    void operationImpl() const override {
        std::cout << "Concrete Implementor A operation" << std::endl;
    }
};

// 具体实现类B
class ConcreteImplementorB : public Implementor {
public:
    void operationImpl() const override {
        std::cout << "Concrete Implementor B operation" << std::endl;
    }
};

// 抽象类
class Abstraction {
protected:
    Implementor* implementor;

public:
    Abstraction(Implementor* impl) : implementor(impl) {}

    virtual void operation() const = 0;
};

// 扩充抽象类
class RefinedAbstraction : public Abstraction {
public:
    RefinedAbstraction(Implementor* impl) : Abstraction(impl) {}

    void operation() const override {
        implementor->operationImpl();
    }
};

int main() {
    Implementor* implA = new ConcreteImplementorA();
    Implementor* implB = new ConcreteImplementorB();

    Abstraction* abs1 = new RefinedAbstraction(implA);
    Abstraction* abs2 = new RefinedAbstraction(implB);

    abs1->operation();
    abs2->operation();

    delete abs2;
    delete abs1;
    delete implB;
    delete implA;

    return 0;
}

        在上述示例中,定义了 Implementor 实现类接口和两个具体实现类 ConcreteImplementorA 和 ConcreteImplementorB。然后定义了抽象类 Abstraction,它维护了一个对实现类的引用,并定义了抽象方法 operation。最后,定义了扩充抽象类 RefinedAbstraction,它通过组合的方式调用了实现类的方法。

        在 main 函数中,创建了具体实现类的对象,并将其传递给扩充抽象类,通过调用 operation 方法来间接调用具体实现类的方法,从而实现了抽象部分与实现部分的解耦。

7. Flyweight(享元模式)

        享元模式(Flyweight Pattern)是一种结构型设计模式,它旨在通过共享对象来减少内存使用和提高性能该模式适用于存在大量相似对象,且这些对象可以共享部分状态的情况

        在 C++ 中,享元模式通常涉及以下几个角色:

        ①. Flyweight(享元接口):定义共享对象的接口,可以接受外部状态作为参数。

        ②. ConcreteFlyweight(具体享元类):实现享元接口,并存储内部状态。具体享元类通常是可共享的

        ③. UnsharedConcreteFlyweight(非共享具体享元类):如果享元对象不可共享,则创建非共享具体享元类。

        ④. FlyweightFactory(享元工厂):用于创建和管理享元对象,通常实现了享元对象的池化管理

        以下是模式示例:

#include <iostream>
#include <unordered_map>

// 享元接口
class Flyweight {
public:
    virtual void operation(int extrinsicState) const = 0;
};

// 具体享元类
class ConcreteFlyweight : public Flyweight {
private:
    int intrinsicState;

public:
    ConcreteFlyweight(int intrinsicState) : intrinsicState(intrinsicState) {}

    void operation(int extrinsicState) const override {
        std::cout << "Concrete Flyweight with intrinsic state " << intrinsicState;
        std::cout << " and extrinsic state " << extrinsicState << std::endl;
    }
};

// 享元工厂
class FlyweightFactory {
private:
    std::unordered_map<int, Flyweight*> flyweights;

public:
    Flyweight* getFlyweight(int key) {
        if (flyweights.find(key) != flyweights.end()) {
            return flyweights[key];
        } else {
            // 通过共享具有相同内部状态的享元对象,可以减少内存使用和提高性能;
            Flyweight* flyweight = new ConcreteFlyweight(key);
            flyweights[key] = flyweight;
            return flyweight;
        }
    }

    ~FlyweightFactory() {
        for (auto& pair : flyweights) {
            delete pair.second;
        }
        flyweights.clear();
    }
};

int main() {
    FlyweightFactory factory;

    Flyweight* flyweight1 = factory.getFlyweight(1);
    flyweight1->operation(100);

    Flyweight* flyweight2 = factory.getFlyweight(2);
    flyweight2->operation(200);

    Flyweight* flyweight3 = factory.getFlyweight(1);
    flyweight3->operation(300);

    delete flyweight3;
    delete flyweight2;
    delete flyweight1;

    return 0;
}

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

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

相关文章

数学建模——线性回归模型

目录 1.线性回归模型的具体步骤和要点&#xff1a; 1.收集数据&#xff1a; 2.探索性数据分析&#xff1a; 3.选择模型&#xff1a; 4.拟合模型&#xff1a; 5.评估模型&#xff1a; 1.R平方&#xff08;R-squared&#xff09;&#xff1a; 2.调整R平方&#xff08;Ad…

Windows11系统配置WSL2网络使它支持LAN访问

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、WSL2安装二、使用步骤1.NAT2.镜像 三、写在最后总结 前言 WSL2的出现感觉真的是一个惊喜&#xff0c;又想玩Linux&#xff0c;又怕日用搞不了的最佳替代方…

TreeMap详解:Java 有序 Map 原理与实现

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

[初学者必看]JavaScript 简单实际案例练习,锻炼代码逻辑思维

文章目录 创意小项目合集&#xff1a;从简易图片轮播到购物车1. 图片轮播器2. 动态列表3. 模态框&#xff08;Modal&#xff09;4. 简单的表单验证5. 简易待办事项列表&#xff08;Todo List&#xff09;6. 简易图片画廊7. 简易时钟8. 简易搜索框高亮9. 简易颜色选择器10. 简易…

【知识碎片】2024_05_14

本篇记录了两道关于位运算的选择题&#xff0c;和一道有点思维的代码题。 C语言碎片知识 求函数返回值&#xff0c;传入 -1 &#xff0c;则在64位机器上函数返回&#xff08; &#xff09; int func(int x) {int count 0;while (x){count;x x&(x - 1);//与运算} return c…

java项目之实验室管理系统(springboot+vue+mysql)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的实验室管理系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 实验室管理系统的主要使用…

OpenAI 推出革命性新模型 GPT-4o:全能AI的新纪元

GPT-4o 模型的推出预示着人工智能领域的又一次飞跃&#xff0c;它将如何改变我们的世界&#xff1f; 在人工智能的快速发展浪潮中&#xff0c;OpenAI 再次站在了技术革新的前沿。2024年5月14日&#xff0c;OpenAI 宣布了其最新旗舰模型 GPT-4o&#xff0c;这不仅是一个简单的版…

2024CCPC全国邀请赛(郑州)暨河南省赛

2024CCPC全国邀请赛&#xff08;郑州站&#xff09;暨河南省赛 一铜一银&#xff0c;虽不是线下第一次参赛但是第一次拿xcpc奖牌&#xff0c;还有个国赛奖真是不戳。感谢学长&#xff0c;感谢队友&#xff01; 虽然遗憾没有冲到省赛金&#xff0c;不过还有icpc商丘&#xff08…

HTTP基础概念和HTTP缓存技术

什么是HTTP HTTP是超文本传输协议&#xff0c;主要分为三个部分&#xff1a;超文本、传输、协议。 超文本是指&#xff1a;文字、图片、视频的混合体。传输是指&#xff1a;点与点之间的信息通信。协议是指&#xff1a;通信时的行为规范或约定 HTTP常见字段 字段名 解释 例…

Android存储文件路径的区别

一、Android存储简介 Android系统分为内部存储和外部存储 从Android6.0开始不断在更新存储权限 外部存储路径的开头&#xff1a;storage/emulated/0 内部存储文件路径的开头&#xff1a;/data/user/0/应用的包名&#xff08;packageName&#xff09; 在设备上对应的目录为/data…

Leetcode2105. 给植物浇水 II

Every day a Leetcode 题目来源&#xff1a;2105. 给植物浇水 II 解法1&#xff1a;双指针 设 Alice 当前下标为 i&#xff0c;初始化为 0&#xff0c;水量为 a&#xff0c;初始化为 capacityA&#xff1b;Bob 当前下标为 j&#xff0c;初始化为 n-1&#xff0c;水量为 b&am…

flutter开发实战-compute将工作交由isolate处理

flutter开发实战-compute将工作交由isolate处理 最近查看flutter文档时候&#xff0c;看到了compute可以将工作交由isolate处理。通过 Flutter 提供的 compute() 方法将解析和转换的工作移交到一个后台 isolate 中。这个 compute() 函数可以在后台 isolate 中运行复杂的函数并…

string功能介绍(普及版)

目录 1。初始化&#xff08;好几种方式&#xff09;&#xff0c;npos和string的使用说明 2。string的拷贝&#xff0c;隐式类型转换&#xff0c;[]&#xff0c;size&#xff0c;iterator&#xff0c;begin&#xff0c;end&#xff0c;reverse&#xff0c;reverse_iterator&am…

回归预测 | Matlab实现DBO-ESN蜣螂算法优化回声状态网络多输入单输出回归预测

回归预测 | Matlab实现DBO-ESN蜣螂算法优化回声状态网络多输入单输出回归预测 目录 回归预测 | Matlab实现DBO-ESN蜣螂算法优化回声状态网络多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现DBO-ESN蜣螂算法优化回声状态网络多输入单输出…

图像融合-下游任务(目标检测、实例分割、深度估计、局部区域细节放大)

下游任务: 采用目标检测、实例分割和深度估计的下游任务来验证图像融合结果质量。 文章目录 下游任务:1.目标检测2.实例分割3.深度估计局部细节放大工具Update1.目标检测 YOLOv8:https://github.com/ultralytics/ultralytics 步骤内容第一步下载项目到本地第二步安装READ…

20232810 2023-2024-2 《网络攻防实践》实验九

一、实践内容 1.1 反汇编 1.1.1 编程原理 编程的原理是一套指导软件开发和维护的概念、原则和实践&#xff0c;包括抽象以简化复杂系统、模块化以分解程序、封装以隐藏内部状态、继承以共享特性、多态以允许不同响应、算法和数据结构以组织计算和存储、控制结构以控制流程、…

Spring Cloud系列—Spring Cloud Gateway服务网关的部署与使用指南

Gateway网关 文章目录 Gateway网关1. 网关基本简介1.1 什么是网关1.2 为什么需要网关&#xff1f; 2. 快速搭建gateway网关2.1 创建新模块2.2 引入依赖2.3 编写启动类2.4 配置路由规则2.5 测试 3. 路由过滤4. 过滤器4.1 简介4.2 网关过滤器4.2.2 种类 4.3 自定义过滤器4.3.1 自…

windows11 Django环境安装

相关文档 1、验证python和pip3环境 C:\Users\Administrator>python Python 3.12.3 (tags/v3.12.3:f6650f9, Apr 9 2024, 14:05:25) [MSC v.1938 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for…

Linux修改终端命令颜色

1.在家目录中修改.bashrc文件 cd ~ vim .bashrc2.找到PS1相关段落&#xff0c;把其他的注释掉&#xff0c;填上该行代码&#xff0c;修改为自己设置的颜色 (具体颜色查看参考文章) 提供两种颜色&#xff0c;其他的自学调色盘吧(下文有)~ (祝你愉快) ①浅蓝色 深蓝 PS1\[\03…

Ubuntu环境搭建与共享文件

vmtool 然后依次执行以下指令 sudo apt-get update 更新包列表。访问系统的软件仓库源,检查所有已知软件包的最新版本,并更新本地数据库,使得可以安装或升级到最新的软件版本。sudo apt-get upgrade 升级所有已安装的软件包到它们的最新版本。这不包括新安装的软件包,仅限…