此为设计模式第十一谈!
用总-分-总的结构和生活化的例子给你讲解设计模式!
码农不易,各位学者学到东西请点赞收藏支持支持!
开始部分:
总:组合模式的目的:让客户端不再区分操作的是组合对象还是叶子对象,都以一个统一的方式来操作。
分:
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; // 程序结束
}