当前位置: 首页 > article >正文

带你深入浅出设计模式:十一、组合实体模式:软件世界的乐高积木

此为设计模式十一谈!

总-分-总的结构生活化的例子给你讲解设计模式!

码农不易,各位学者学到东西请点赞收藏支持支持!

开始部分:

总:组合模式的目的:让客户端不再区分操作的是组合对象还是叶子对象,都以一个统一的方式来操作。

分:

1.老规矩,自行在vs创建一个控制台应用

2.实现编码,此处用文件夹例子来辅助理解

2.1 抽象组件对象,此处为文件条目,可以实现为文件和文件夹

2.2 叶子节点对象,此处为文件

2.3 组合节点对象,此处为文件夹

// 引入必要的头文件
#include <iostream>          // 用于输入输出
#include <string>            // 用于处理字符串
#include <vector>            // 用于创建动态数组

// 基础接口,所有文件和文件夹都应继承自这个接口
class FileItem {
public:
    virtual ~FileItem() {}  // 虚析构函数,确保派生类对象可以正确析构

    // 添加文件项
    virtual void add(FileItem*) = 0;  

    // 移除文件项
    virtual void remove(FileItem*) = 0;  

    // 打印文件或文件夹名称,带前缀
    virtual void print(std::string prefix) const = 0;  

    // 判断是否是文件夹
    virtual bool is_folder() const = 0;  

    // 获取名称
    virtual std::string get_name() const = 0;  
};

// 文件类 - 叶子节点
class File : public FileItem {
private:
    std::string name;  // 文件名

public:
    // 构造函数,初始化文件名
    File(const std::string& n): name(n) {}

    // 叶子节点不支持添加操作
    void add(FileItem*) override { /* 不做任何事情 */ }

    // 叶子节点不支持移除操作
    void remove(FileItem*) override { /* 不做任何事情 */ }

    // 打印文件名称,带前缀
    void print(const std::string& prefix) const override {
        std::cout << prefix << "-" << get_name() << std::endl;
    }

    // 文件不是文件夹
    bool is_folder() const override {
        return false;
    }

    // 获取文件名
    std::string get_name() const override {
        return name;
    }
};

// 文件夹类 - 组合节点
class Folder : public FileItem {
private:
    std::string name;  // 文件夹名
    std::vector<FileItem*> items;  // 文件夹里的元素

public:
    // 构造函数,初始化文件夹名
    Folder(const std::string& n): name(n) {}

    // 添加文件或文件夹
    void add(FileItem* item) override {
        items.push_back(item);
    }

    // 移除文件或文件夹
    void remove(FileItem* item) override {
        auto iter = std::find(items.begin(), items.end(), item);
        if(iter != items.end()) {
            delete *iter;  // 释放对象内存
            items.erase(iter);  // 从vector移除指针
        }
    }

    // 打印文件夹名称,然后递归打印所有子元素
    void print(const std::string& prefix) const override {
        std::cout << prefix << "+" << get_name() << std::endl;
        for(auto* item : items) {
            item->print(prefix + " ");  // 递归打印子元素
        }
    }

    // 文件夹是文件夹
    bool is_folder() const override {
        return true;
    }

    // 获取文件夹名
    std::string get_name() const override {
        return name;
    }
};

int main() {
    Folder home_folder("Home");  // 创建根目录

    File file1("report.txt");  // 创建文件
    File file2("summary.txt");  // 创建文件
    Folder documents("Documents");  // 创建文件夹
    documents.add(&file1);  // 将文件添加到文件夹
    documents.add(&file2);  // 将文件添加到文件夹
    home_folder.add(&documents);  // 将文件夹添加到根目录

    File file3("code.cpp");  // 创建文件
    Folder projects("Projects");  // 创建文件夹
    projects.add(&file3);  // 将文件添加到文件夹
    home_folder.add(&projects);  // 将文件夹添加到根目录

    home_folder.print("");  // 打印目录结构

    return 0;  // 程序结束
}

总:组合模式的优点:统一组合对象和叶子对象;简化客户端的调用;缺点:很难限制组合中的组件类型。


http://www.kler.cn/news/342090.html

相关文章:

  • 日语学习零基础生活日语口语柯桥外语学校|股票用日语怎么说?
  • threejs-基础材质设置
  • 软件项目开发流程与团队分工整体认知——基于《信息系统项目管理师教程》(需求分析、系统设计、开发、测试、部署与运维、开发工具与管理软件)
  • 【C++篇】虚境探微:多态的流动诗篇,解锁动态的艺术密码
  • leetcode---素数,最小质因子,最大公约数
  • 回归分析在数据挖掘中的应用简析
  • x86 架构下一些常用的汇编指令英文全称与功能简述
  • 商标恶意维权形式及应对策略
  • nn.Identity()
  • 噪声分布 双峰,模拟函数 或者模拟方法 python人工智能 深度神经网络
  • 量化交易四大邪术终章:春梦了无痕
  • 239. 滑动窗口最大值
  • 重学SpringBoot3-集成Redis(五)之布隆过滤器
  • 国内的无人机行业的现状和前景分析
  • 【Java】JAVA知识总结浅析
  • Airtest脚本的重构与优化:提升测试效率和可读性
  • 表面缺陷检测系统源码分享
  • vue 入门二
  • 网络编程(17)——asio多线程模型IOThreadPool
  • Java | Leetcode java题解之第458题可怜的小猪