设计模式之组合模式-一个人的力量是有限的,组合更强大!
一、组合模式的概念
组合模式,又叫部分整体模式,属于结构型模式,是用于把一组相似的对象当作一个单一的对象,
它依据树形结构来组合对象,用来表示“部分-整体”层次,创建一个对象组的树形结构,通过一个对象可以访问整个对象树。
二、组合模式使用场景
1、用来表示对象的“部分-整体”层次结构时可以使用组合模式。
2、希望用户忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象。
三、组合模式构建方法
1、抽象构件类
提供客户端可以调用的抽象接口,为叶子构件和容器构件对象定义接口。
2、容器构件类
容器构件包含子节点,它包含了一个存储子节点容器,实现了抽象构件中定义的接口,包括访问及管理子构件的接口,可以递归调用其子节点的业务方法。
3、叶子构件类
叶子节点没有子节点,它实现了 抽象构件中定义的行为,但是对于访问及管理子构件的接口,需要通过异常等方式进行处理。
四、组合模式的示例
// ComponentPattern.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <string>
#include <vector>
#define DELETE_PTR(p) {if(p!=nullptr){delete (p); (p)=nullptr;}}
using namespace std;
// 抽象构件类
class ComponentCompany
{
public:
ComponentCompany(string strName)
{
m_strName = strName;
}
virtual ~ComponentCompany(){}
virtual void add(ComponentCompany *pComponentCompany) = 0;
virtual void remove(ComponentCompany *pComponentCompanyp) = 0;
virtual ComponentCompany *getChild(int index) = 0;
virtual void showChild() = 0;
protected:
string m_strName;
};
// 容器构件类
class CompositeCompany : public ComponentCompany
{
public:
CompositeCompany(string strName) : ComponentCompany(strName){}
virtual ~CompositeCompany()
{
while (!m_comElemsVector.empty())
{
vector<ComponentCompany *>::iterator it = m_comElemsVector.begin();
DELETE_PTR(*it);
m_comElemsVector.erase(it);
}
}
void add(ComponentCompany *pComponentCompany)
{
m_comElemsVector.push_back(pComponentCompany);
}
void remove(ComponentCompany *pComponentCompany)
{
for (auto *iter : m_comElemsVector)
{
if (iter == pComponentCompany)
{
DELETE_PTR(pComponentCompany);
break;
}
}
}
ComponentCompany *getChild(int index)
{
if (index >= m_comElemsVector.size())
{
return nullptr;
}
return m_comElemsVector.at(index);
}
void showChild()
{
cout << m_strName << endl;
for (auto *iter : m_comElemsVector)
{
iter->showChild();
}
}
private:
vector<ComponentCompany *> m_comElemsVector;
};
// 叶子构件类
class LeafDepart : public ComponentCompany
{
public:
LeafDepart(string strName) : ComponentCompany(strName) {}
virtual ~LeafDepart(){}
void add(ComponentCompany *pComponentCompany)
{
cout << "LeafDepart Node Can't add a leaf!" << endl;
}
void remove(ComponentCompany *pComponentCompany)
{
cout << "Can't remove a leaf from LeafDepart Node!" << endl;
}
ComponentCompany *getChild(int index)
{
cout << "Can't getChild a leaf from LeafDepart Node!" << endl;;
return nullptr;
}
void showChild()
{
cout << m_strName << endl;;
}
};
int main()
{
cout << "-------------组合模式--------------" << endl;
// 总公司
ComponentCompany *pHeadCompany = new CompositeCompany("-总公司");
// 子公司
ComponentCompany *pBranchCompany = new CompositeCompany("-------子公司");
pBranchCompany->add(new LeafDepart("-------------子公司研发部"));
pBranchCompany->add(new LeafDepart("-------------子公司产品部"));
pBranchCompany->add(new LeafDepart("-------------子公司测试部"));
pBranchCompany->add(new LeafDepart("-------------子公司网络部"));
pHeadCompany->add(pBranchCompany);
pHeadCompany->add(new LeafDepart("-------总公司研发部"));
pHeadCompany->add(new LeafDepart("-------总公司产品部"));
pHeadCompany->add(new LeafDepart("-------总公司测试部"));
pHeadCompany->add(new LeafDepart("-------总公司网络部"));
pHeadCompany->showChild();
//DELETE_PTR(pBranchCompany);调用下面的删除时,会自动在析构函数中删除该指针
DELETE_PTR(pHeadCompany);
std::cout << "Hello World!\n";
getchar();
}
运行结果:
五、组合模式的优缺点
优点:
1、可以方便的实现树形结构,为树形结构提供一种灵活的处理方案。
2、单个对象和组合对象具有一致性,简化客户端调用接口。
3、清楚定义了“部分-整体”的层次结构,方便对整个层次的管理与控制。
4、方便扩展增加容器结构和叶子结构,无需对现有的类做任何修改。
缺点:
1、太过复杂的业务规则,使用组合模式难度比较大、设计抽象比较困难,有时候很多方法并不适用于所有的叶子构件类,需要做异常处理。
能力有限,如有错误,多多指教。。。
本文为博主原创文章,未经博主允许请勿转载!作者:ISmileLi