组合模式作为结构型模式的一种,主要用于将对象组合成树形结构以表示“部分-整体”的层次结构。组合(Composite)模式使得用户对单个对象和组合对象的使用具有一致性。
常见的场景有如下两种:
公司结构:公司内存在各个部门,同时公司存在子公司;子公司内又存在各个部门,更有甚者子公司内仍存在子公司
文件系统:文件夹内既有文件也有子文件夹,子文件夹内也有文件和它的子文件夹
两者均体现了整体层次上的树形结构,且子结构中存在具有和父结构相同属性的结构。
思想
组合模式的核心思想是模块化并复用模块
代码示例
仅以上文提到的文件系统为例,书写其实现代码:
// 抽象基类:定义组件接口
class FileSystemComponent {
public:
virtual ~FileSystemComponent() = default;
virtual void displayInfo() const = 0;
};
// 叶子节点:具体文件类
class File final : public FileSystemComponent {
private:
std::string fileName_;
public:
File(const std::string& name) : fileName_(name) {}
void displayInfo() const override {
std::cout << " File: " << fileName_ << std::endl;
}
};
// 容器节点:目录类
class Directory final : public FileSystemComponent {
private:
std::string dirName_;
std::vector<std::shared_ptr<FileSystemComponent>> components_;
public:
Directory(const std::string& name) : dirName_(name) {}
void addComponent(std::shared_ptr<FileSystemComponent> component) {
components_.push_back(component);
}
void displayInfo() const override {
std::cout << "Directory: " << dirName_ << std::endl;
for (const auto& comp : components_) {
comp->displayInfo();
}
}
};
// 主函数示例
int test_comp() {
auto rootDir = std::make_shared<Directory>("Root");
auto docs = std::make_shared<Directory>("Documents");
auto file0 = std::make_shared<File>("file.txt");
auto file1 = std::make_shared<File>("file1.txt");
auto file2 = std::make_shared<File>("file2.txt");
docs->addComponent(file1);
docs->addComponent(file2);
rootDir->addComponent(file0);
rootDir->addComponent(docs);
rootDir->displayInfo(); // 展示目录结构
return 0;
}
//ouput:
/*
Directory: Root
File: file.txt
Directory: Documents
File: file1.txt
File: file2.txt
*/
如上代码文件夹和文件继承自同一个抽象基类,文件夹内可以持有的是抽象基类的指针,进而可以保证文件夹内可以含有文件夹和文件,形成树形结构。
总结
本文在说明组合模式是用于表征树形结构的“整体-部分”关系的基础上,通过两个人尽皆知的例子——文件系统和集团公司系统——阐释了组合模式的应用场景,并结合代码示例进行说明。
感谢您的关注、点赞、留言