今天研究了一下设计模式15 组合模式 本人是菜鸟一枚,所以一开始完全不懂组合究竟是什么意思。先上图一张,树形结构图:
文档说,如果想做出这样的结构,通常考虑组合模式。那是为什么呢?现在让我们看一下组合模式的类图一本结构
想了很久,结合源代码,才搞明白,其实这个组合,意思就是说,如果我们要做这种树状结果,比如公司想让我们吧所有部门人员的 姓名,职位,薪水遍历出来,这个时候怎么办呢?那我们看树状机构图,有叶子结点和枝干结点,2种,但是2种有共性,那就是每个结点都有姓名,职位,薪水。所有叶子结点和枝干结点共同继承结点接口。因为枝干结点本身还有子结点,而且子结点里面,即可能有叶子结点,也可能有枝干结点,二者不是同一个类型啊,怎么解决呢? 因为 二者都继承了共同的基类 所以 对于枝干结点,我们给其添加属性成员 vector<Component*> s,这样S中既可以存放叶子结点,也可以存放枝干结点,这个地方就体现了 1....n 这个意义。同时也解决了一个容器存储不同类型的问题。
我估计我说的大家也不是特别理解,下面上源代码,结合源代码,相信您会明白的。
1.zuhepattern.h #include<string> #include<iostream> #include<vector> using namespace std; class CCorpNode { public: CCorpNode(); CCorpNode(string _name,string _pos,int _salary); virtual ~CCorpNode(); 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; }; class CBranchNode:public CCorpNode { public: CBranchNode(); CBranchNode(string name,string pos,int salary); ~CBranchNode(); void add(CCorpNode *pcorpNode); vector<CCorpNode*> GetSubordinateInfo(); bool IsLeaf(); private: vector<CCorpNode*> m_subordinateList; }; class CLeafNode:public CCorpNode { public: CLeafNode(); CLeafNode(string name ,string pos,int salary); ~CLeafNode(); bool IsLeaf(); }; //实现部分 #include "stdafx.h" #include "zuhepattern.h" CCorpNode::CCorpNode() { this->m_name=""; this->m_position=""; this->m_salary=0; } CCorpNode::CCorpNode(string _name,string _pos,int _salary):m_name(_name),m_position(_pos),m_salary(_salary) { } CCorpNode::~CCorpNode(){} string CCorpNode::GetInfo() { char ss[10]; itoa(this->m_salary,ss,10); string info=""; info=info+"姓名:"+this->m_name; info=info+" 职位:"+this->m_position; info=info+" 薪水:"+ss; return info; } void CCorpNode::setParent(CCorpNode* _pParent) { this->m_pParent=_pParent; } CCorpNode* CCorpNode::GetParent() { return this->m_pParent; } CBranchNode::CBranchNode(){ this->m_isLeaf=false; } CBranchNode::CBranchNode(string name, string pos, int salary):CCorpNode(name, pos, salary) { this->m_isLeaf=false; } CBranchNode::~CBranchNode(){} void CBranchNode::add(CCorpNode* pcorpNode) { this->setParent(this); this->m_subordinateList.push_back(pcorpNode); } vector<CCorpNode*> CBranchNode::GetSubordinateInfo() { return this->m_subordinateList; } bool CBranchNode::IsLeaf() { return this->m_isLeaf; } CLeafNode::CLeafNode() { this->m_isLeaf=true; } CLeafNode::CLeafNode(string name ,string pos,int salary):CCorpNode(name, pos, salary) { this->m_isLeaf=true; } CLeafNode::~CLeafNode(){} bool CLeafNode::IsLeaf() { return this->m_isLeaf; } //main函数部分 #include "stdafx.h" #include <string> #include<iostream> #include "zuhepattern.h" using namespace std; static CBranchNode compositeCorpTree() { //根节点 CBranchNode root("王大麻子","总经理",100000); //三个部门经理--树叉 CBranchNode developDep("刘大瘸子","研发部经理",10000); CBranchNode saleDep("马二拐子","销售部门经理",10000); CBranchNode financeDep("赵三驼子","研发部经理",10000); CBranchNode fistDevGroup("杨三","开发一组长",8000); CBranchNode secondDevGroup("李四","开发二组长",8000); //叶子结点 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","销售人员",2000); CLeafNode i("i","销售人员",2000); CLeafNode j("j","财务人员",2000); CLeafNode k("k","ceo秘书",2000); CLeafNode zhenglaoliu("郑老六","研发部副经理",2000); //开始组装 //CEO下有三个部门经理和一个秘书 root.add(&k); root.add(&developDep); root.add(&saleDep); root.add(&financeDep); //研发部经理 developDep.add(&zhenglaoliu); developDep.add(&fistDevGroup); developDep.add(&secondDevGroup); //开发组成员 fistDevGroup.add(&a); fistDevGroup.add(&b); fistDevGroup.add(&c); secondDevGroup.add(&d); secondDevGroup.add(&e); secondDevGroup.add(&f); secondDevGroup.add(&g); secondDevGroup.add(&a); //销售部人员 saleDep.add(&h); saleDep.add(&i); //最后一个财务 financeDep.add(&j); return root; } static string getTreeInfo(CBranchNode root) { vector<CCorpNode*> subordinatelist=root.GetSubordinateInfo(); string info=""; for(vector<CCorpNode*>::iterator ts=subordinatelist.begin();ts!=subordinatelist.end();++ts) { if((*ts)->IsLeaf()) { info=info+(*ts)->GetInfo()+" "; }else { info=info+(*ts)->GetInfo()+" "+getTreeInfo(*((CBranchNode*)*ts)); //基类对象是无法转为子类对象的,所以要先由基类指针转为子类指针,再转为子类对象。 } } return info; } int main(int argc, _TCHAR* argv[]) { CBranchNode ceo=compositeCorpTree(); cout<<ceo.GetInfo()<<endl; cout<<getTreeInfo(ceo)<<endl; int i=1; cin>>i; return 0; }