定义
组合模式(Composite Pattern)是一种结构型设计模式,它将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
结构
-
Component(抽象组件) :为组合对象中的对象声明接口,实现默认行为,可以是接口或抽象类。
-
Leaf(叶子节点) :叶子节点是组合中最基本的组成部分,它没有子节点。
-
Composite(复合节点) :复合节点是有子节点的节点,它实现了
Component
接口,并且存储子节点,定义与子节点有关的行为。
优点
-
定义了包含叶子对象和组合对象的类层次结构:用户可以一致地使用组合对象和单个对象。
-
简化客户端代码:客户代码可以一致地处理单个对象和组合对象,而不需要关心它们的区别。
-
更容易增加新的类型:可以通过扩展叶子节点或组合节点来添加新类型,无需修改现有代码。
代码示例
公司管理系统
#include <iostream>
#include <vector>
// 公司抽象类
class Company
{
protected:
std::string name;
public:
explicit Company(const std::string& name) : name(name) {}
virtual void add(std::shared_ptr<Company> company) = 0; // 增加
virtual void remove(std::shared_ptr<Company> company) = 0; // 移除
virtual void display(int depth) const = 0; // 显示
virtual void lineOfDuty() const = 0; // 履行职责
};
// 具体分公司类,树枝节点
class ConcreteCompany : public Company
{
protected:
std::vector<std::shared_ptr<Company>> children;
public:
explicit ConcreteCompany(const std::string& name) : Company(name) {}
void add(std::shared_ptr<Company> company) override
{
children.push_back(company);
}
void remove(std::shared_ptr<Company> company) override
{
children.erase(std::remove(children.begin(), children.end(), company), children.end());
}
void display(int depth) const override
{
std::string indent(depth, '-');
std::cout << indent << name << std::endl;
for (const auto& child : children)
{
child->display(depth + 2);
}
}
void lineOfDuty() const override
{
for (const auto& child : children)
{
child->lineOfDuty();
}
}
};
// 部门类,树叶节点
class Department : public Company
{
public:
explicit Department(const std::string& name) : Company(name) {}
void add(std::shared_ptr<Company> company) override
{
throw std::runtime_error("Cannot add to a department");
}
void remove(std::shared_ptr<Company> company) override
{
throw std::runtime_error("Cannot remove from a department");
}
void display(int depth) const override
{
std::string indent(depth, '-');
std::cout << indent << name << std::endl;
}
void lineOfDuty() const override
{
std::cout << name << " : Performing duties" << std::endl;
}
};
int main()
{
std::shared_ptr<Company> root = std::make_shared<ConcreteCompany>("Head Office");
std::shared_ptr<Company> branch1 = std::make_shared<ConcreteCompany>("Branch Office 1");
std::shared_ptr<Company> branch2 = std::make_shared<ConcreteCompany>("Branch Office 2");
root->add(branch1);
root->add(branch2);
std::shared_ptr<Company> dept1 = std::make_shared<Department>("HR Department");
std::shared_ptr<Company> dept2 = std::make_shared<Department>("Finance Department");
branch1->add(dept1);
branch2->add(dept2);
std::cout << "Company Structure: " << std::endl;
root->display(1);
std::cout << "\nLine of Duty: " << std::endl;
root->lineOfDuty();
system("pause");
return 0;
}
应用场景
-
希望表示对象的部分-整体层次结构。
-
希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。