15.1.解釋
概念:將對象組合成樹形結構以表示“部分-整體”的層次結構。Composite使得用戶對單個對象和組合的使用具有一致性。
main(),客戶
CCorpNode,抽象基類,實現基本信息
CBranchNode,樹枝節點,實現Addordinate()函數和GetSubordinate()函數
CLeafNode,葉子節點,IsLeaf屬性總是“true”
說明:組合模式主要是實現在CBranchNode對象裏增加對其它對象的數組,如vector<CCorpNode*>,數組裏可以存放CBranchNode和CLeafNode對象。這樣方便進行遍歷操作。
注意:組合模式有透明組合模式和安全組合模式。透明組合模式是將Addordinate和GetSubordinate這兩個函數也抽象到CCorpNode基類裏,這增加了操作葉子節點的難度,更易出現邏輯問題。所以儘量使用安全模式。
這個簡單了,可以想像一下TreeView和TreeNode基本上是這個意思了,將很多數據組織在一塊。
看代碼:
//CorpNode.h
#pragma once
#include <iostream>
using std::string;
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;
};
//CorpNode.cpp
#include "StdAfx.h"
#include "CorpNode.h"
#include "..\CommonDeclare\Convert.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薪水:");
info.append(CConvert::ToString(this->m_salary));
return info;
}
void CCorpNode::SetParent( CCorpNode *_parent )
{
this->m_pParent = _parent;
}
CCorpNode * CCorpNode::GetParent()
{
return this->m_pParent;
}
//BranchNode.h
#pragma once
#include "corpnode.h"
#include "CorpNode.h"
#include <vector>
#include <iostream>
using std::vector;
using std::string;
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;
};
//BranchNode.cpp
#include "StdAfx.h"
#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.h
#pragma once
#include "corpnode.h"
class CLeafNode :
public CCorpNode
{
public:
CLeafNode(void);
CLeafNode(string name, string pos, int salary);
~CLeafNode(void);
bool IsLeaf();
};
//LeafNode.cpp
#include "StdAfx.h"
#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;
}
曾經開發過一款Gantt圖的控件,採用的就是這種模式,有GanttView和GanttNode兩個類,IGanttNode一個接口,GanttScale標尺類。GanttView負責顯示,GanttNode是實現類,只有一個GanttNode類來實現數據的組合,IGanttNode指示了一個IGanttNodeCollection屬性來記錄所有下級結點的集合。算是實踐中的一個應用吧。