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

此为设计模式十一谈!

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

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

开始部分:

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

分:

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;  // 程序结束
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值