组合设计模式适用于以下情况:
• 你想表示对象的部分------整体层次结构;
• 你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象;
下面是一个组合模式的示例程序:
cpp
#include <iostream>
#include <vector>
#include <string>
#include <memory>
// 1. The Component Interface ------ Defines common operations for both files and folders
class FileSystemNode {
protected:
std::string name_;
public:
FileSystemNode(const std::string& name) : name_(name) {}
virtual ~FileSystemNode() = default;
virtual void display(int depth = 0) const = 0;
};
// 2. The Leaf Node ------ Represents individual files that cannot contain anything else
class File : public FileSystemNode {
private:
int size_; // Unique attribute for files
public:
File(const std::string& name, int size) : FileSystemNode(name), size_(size) {}
void display(int depth = 0) const override {
// Print spaces based on the tree depth for indentation
std::string indent(depth * 2, ' ');
std::cout << indent << "- 📄 File: " << name_ << " (" << size_ << " KB)\n";
}
};
// 3. The Composite Node ------ Represents folders that can contain both files and other folders
class Folder : public FileSystemNode {
private:
// A collection storing child nodes polymorphically
std::vector<std::unique_ptr<FileSystemNode>> children_;
public:
Folder(const std::string& name) : FileSystemNode(name) {}
// Method to add items into the folder
void add(std::unique_ptr<FileSystemNode> node) {
children_.push_back(std::move(node));
}
void display(int depth = 0) const override {
std::string indent(depth * 2, ' ');
std::cout << indent << "📁 Folder: " << name_ << "\n";
// Recursively trigger display() on all children without worrying about their exact type
for (const auto& child : children_) {
child->display(depth + 1);
}
}
};
// 4. Client Code
int main() {
// Create the top-level root folder
auto rootFolder = std::make_unique<Folder>("Root");
// Create standalone files and a sub-folder
auto file1 = std::make_unique<File>("Config.ini", 4);
auto subFolder = std::make_unique<Folder>("Projects");
auto projectFile1 = std::make_unique<File>("main.cpp", 12);
auto projectFile2 = std::make_unique<File>("README.md", 2);
// Assemble the tree structure
subFolder->add(std::move(projectFile1));
subFolder->add(std::move(projectFile2));
rootFolder->add(std::move(file1));
rootFolder->add(std::move(subFolder)); // Nesting a folder inside a folder
// Uniform treatment: Call display on the root, and the entire tree renders automatically
std::cout << "--- Printing Directory Tree ---\n";
rootFolder->display();
return 0;
}
程序运行结果如下:
shell
$ g++ -o main main.cpp
$ ./main
--- Printing Directory Tree ---
📁 Folder: Root
- 📄 File: Config.ini (4 KB)
📁 Folder: Projects
- 📄 File: main.cpp (12 KB)
- 📄 File: README.md (2 KB)