组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。
这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。
优点: 1、高层模块调用简单。 2、节点自由增加。
缺点:在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。
使用场景:部分、整体场景,如树形菜单,文件、文件夹的管理。
注意事项:定义时为具体类。
类关系图:
实现思路:1、定义父类,声明为子类共同所有的方法和属性。2、子类再次添加各自不同的方法或者修改部分属性,以区别不同的子类。
运用到技术:递归函数。
CorpNode.h
#pragma once
#include
#include
using namespace std;
class CCorpNode
{
public:
CCorpNode();
CCorpNode(string _name, string _pos, int _salary);
virtual ~CCorpNode(void);
virtual string GetInfo();
void SetParent(CCorpNode *_pParent);
CCorpNode * GetParent();
virtual bool IsLeaf() = 0;
private:
string m_name;
string m_position;
int m_salary;
protected:
bool m_isLeaf;
CCorpNode *m_pParent;
};
BranchNode.h
#pragma once
#include "corpnode.h"
#include "CorpNode.h"
class CBranchNode :
public CCorpNode
{
public:
CBranchNode(void);
CBranchNode(string name, string pos, int salary);
~CBranchNode(void);
void Add(CCorpNode *pcorpNode);
vector GetSubordinateInfo();
bool IsLeaf();
private:
vector m_subordinateList;
};
LeafNode.h
#pragma once
#include "corpnode.h"
class CLeafNode :
public CCorpNode
{
public:
CLeafNode(void);
CLeafNode(string name, string pos, int salary);
~CLeafNode(void);
bool IsLeaf();
};
CorpNode.cpp
#include "CorpNode.h"
CCorpNode::CCorpNode(void)
{
m_name = "";
m_position = "";
m_salary = 0;
}
CCorpNode::CCorpNode(string _name, string _pos, int _salary) : m_name(_name), m_position(_pos), m_salary(_salary)
{
}
CCorpNode::~CCorpNode(void)
{
}
string CCorpNode::GetInfo()
{
string info = "";
info.append("姓名:");
info.append(this->m_name);
info.append("\t职位:");
info.append(this->m_position);
info.append("\t薪水:");
char buf[50] = {0};
sprintf_s(buf, "%d", this->m_salary);
info.append(buf);
return info;
}
void CCorpNode::SetParent( CCorpNode *_parent )
{
this->m_pParent = _parent;
}
CCorpNode * CCorpNode::GetParent()
{
return this->m_pParent;
}
BranchNode.cpp
#include "BranchNode.h"
CBranchNode::CBranchNode(void)
{
m_isLeaf = false;
}
CBranchNode::CBranchNode( string name, string pos, int salary ) : CCorpNode(name, pos, salary)
{
m_isLeaf = false;
}
CBranchNode::~CBranchNode(void)
{
}
void CBranchNode::Add( CCorpNode *pcorpNode )
{
pcorpNode->SetParent(this);
m_subordinateList.push_back(pcorpNode);
}
vector CBranchNode::GetSubordinateInfo()
{
return this->m_subordinateList;
}
bool CBranchNode::IsLeaf()
{
return m_isLeaf;
}
LeafNode.cpp
#include "LeafNode.h"
CLeafNode::CLeafNode(void)
{
m_isLeaf = true;
}
CLeafNode::CLeafNode( string name, string pos, int salary ) : CCorpNode(name, pos, salary)
{
m_isLeaf = true;
}
CLeafNode::~CLeafNode(void)
{
}
bool CLeafNode::IsLeaf()
{
return m_isLeaf;
}
Composite.cpp
#include "BranchNode.h"
#include "LeafNode.h"
#include
#include
using std::vector;
using std::string;
using std::cout;
using std::endl;
string GetTreeInfo(CBranchNode * proot)
{
vector subordinateList = proot->GetSubordinateInfo();
string info = "";
vector::const_iterator it = subordinateList.begin();
for (; it != subordinateList.end(); it++)
{
if ((*it)->IsLeaf())
{
info.append((*it)->GetInfo());
info.append("\n");
}
else
{
info.append((*it)->GetInfo());
info.append("\n");
info.append(GetTreeInfo(dynamic_cast(*it)));
}
}
return info;
}
void DoNew()
{
CBranchNode root("赵大", "总经理", 100000);
CBranchNode devDep("钱大", "研发部门经理", 10000);
CBranchNode saleDep("孙大", "销售部门经理", 20000);
CBranchNode financeDep("李大", "财务部门经理", 30000);
CBranchNode firstDevGroup("周三也斜", "开发一组组长", 5000);
CBranchNode secondDevGroup("吴大棒槌", "开发二组组长", 6000);
CLeafNode a("a", "开发人员", 2000);
CLeafNode b("b", "开发人员", 2000);
CLeafNode c("c", "开发人员", 2000);
CLeafNode d("d", "开发人员", 2000);
CLeafNode e("e", "开发人员", 2000);
CLeafNode f("f", "开发人员", 2000);
CLeafNode g("g", "开发人员", 2000);
CLeafNode h("h", "开发人员", 5000);
CLeafNode i("i", "开发人员", 4000);
CLeafNode j("j", "开发人员", 5000);
CLeafNode k("k", "CEO秘书", 8000);
CLeafNode zheng("郑老六", "研发部副经理", 20000);
root.Add(&k);//CEO有三个部门经理和一个秘书
root.Add(&devDep);
root.Add(&saleDep);
root.Add(&financeDep);
devDep.Add(&zheng);//开发部有一个副经理和两个小组
devDep.Add(&firstDevGroup);
devDep.Add(&secondDevGroup);
firstDevGroup.Add(&a);
firstDevGroup.Add(&b);
firstDevGroup.Add(&c);
secondDevGroup.Add(&d);
secondDevGroup.Add(&e);
secondDevGroup.Add(&f);
saleDep.Add(&g);
saleDep.Add(&h);
financeDep.Add(&i);
financeDep.Add(&j);
cout << root.GetInfo().c_str() << endl;
cout << GetTreeInfo(&root).c_str() << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
//使用组合模式后的调用。
DoNew();
system("pause");
return 0;
}
参考文献:《菜鸟教程》 https://blog.csdn.net/phiall/article/details/52199659博客