1、组合模式的提出
在软件开发过程中,使用者Client过多依赖所操作对象内部的实现结构,如果对象内部的实现结构频繁发生变化,则使用者的代码结构将要频繁地修改,不利于代码地维护和扩展性;组合模式可以解决此类问题。组合模式可以使用者代码与复杂地操作对象结构进行解耦,根据操作对象的实现结构抽象出一个的基类,让操作对象内部根据需求变化实现复杂数据地操作接口,则使用者使用操作对象提供的统一接口就可完成功能。
2、需求描述
有根节点、子节点、叶子节点,这三种节点都有自己的名字。操作规则:根节点下面可以添加子节点和叶子节点;子节点下面可以添加子子节点和叶子节点;叶子节点下面不能再添加其他节点。
设计一个功能代码,模拟上面的节点添加规则,使用者可以访问这些节点的数据结构。
3、功能实现
(1)UML图如下:
(2)代码实现如下:
#include <iostream>
#include <string>
#include <vector>
class Component
{
protected:
std::string m_strName;
public:
Component(std::string name):m_strName(std::move(name)){};
virtual void operation() const =0;
std::string getName(){return m_strName;};
virtual ~Component(){};
};
class Leaf:public Component
{
public:
explicit Leaf(std::string name):Component(name){
};
virtual void operation() const override
{
std::cout << "Leaf: " << m_strName << std::endl;
};
};
class Composite:public Component
{
private:
std::vector<Component*>m_vecChildren;
public:
explicit Composite(std::string name):Component(name){};
void add(Component* p)
{
m_vecChildren.emplace_back(p);
};
void remove(Component* p)
{
for (auto it = m_vecChildren.begin(); it != m_vecChildren.end(); it++) {
if (*it == p) {
m_vecChildren.erase(it);
std::cout << m_strName << " remove: " << p->getName() << std::endl;
break;
}
}
};
void operation() const override {
std::cout << "Composite: " << m_strName << std::endl;
for (const auto& child : m_vecChildren) {
child->operation();
}
}
~Composite()
{
std::vector<Component*>().swap(m_vecChildren);
std::cout << "~Composite() " << std::endl;
}
};
class Client
{
public:
void doWork()
{
// 创建叶节点
Component* leafNode1 = new Leaf("leafNode 1");
Component* leafNode2 = new Leaf("leafNode 2");
Component* leafNode3 = new Leaf("leafNode 3");
// 创建容器子节点
Composite* childNode1 = new Composite("childNode 1");
Composite* childNode2 = new Composite("childNode 2");
// 将叶节点添加到容器子节点中
childNode1->add(leafNode1);
childNode1->add(leafNode2);
childNode2->add(leafNode3);
// 将容器节点添加到根容器中
Composite* rootNode = new Composite("rootNode");
rootNode->add(childNode1);
rootNode->add(childNode2);
// 调用根容器的操作方法,将逐层遍历整个组合结构并调用每个节点的操作方法
rootNode->operation();
//移除节点
std::cout << "\n" << std::endl;
childNode1->remove(leafNode2);
rootNode->remove(childNode2);
std::cout << "\n" << std::endl;
// 调用根容器的操作方法,将逐层遍历整个组合结构并调用每个节点的操作方法
rootNode->operation();
delete leafNode1;
delete leafNode2;
delete leafNode3;
delete childNode1;
delete childNode2;
delete rootNode;
leafNode1 = nullptr;
leafNode2 = nullptr;;
leafNode3 = nullptr;;
childNode1 = nullptr;;
childNode2 = nullptr;;
rootNode = nullptr;;
}
};
int main()
{
Client obj;
obj.doWork();
return 0;
}
程序运行结果如下: