设计模式之组合模式(Composite)

1、定义

组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。

这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。

2、介绍

优点: 1、高层模块调用简单。 2、节点自由增加。

缺点:在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。

使用场景:部分、整体场景,如树形菜单,文件、文件夹的管理。

注意事项:定义时为具体类。

3、源码

类关系图:

 实现思路:1、定义父类,声明为子类共同所有的方法和属性。2、子类再次添加各自不同的方法或者修改部分属性,以区别不同的子类。

运用到技术:递归函数。

3.1、头文件

CorpNode.h

#pragma once
#include <iostream>
#include<vector>
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<CCorpNode*> GetSubordinateInfo();
	bool IsLeaf();
private:
	vector<CCorpNode*> 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();
};

3.2、实现

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<CCorpNode*> 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 <vector>
#include <iostream>
using std::vector;
using std::string;
using std::cout;
using std::endl;

string GetTreeInfo(CBranchNode * proot)
{
    vector<CCorpNode*> subordinateList = proot->GetSubordinateInfo();
    string info = "";

    vector<CCorpNode*>::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<CBranchNode*>(*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;
}

4、结果

 

参考文献:《菜鸟教程》   https://blog.csdn.net/phiall/article/details/52199659博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值