组合模式
组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构。 -- 百度百科
组合模式能够体现各个对象之间的层次关系,将所有对象设计为同一种类型,从而忽略组合与个体的差异,统一管理起来。
意义
组合模式将所有的对象统一管理,并按照树形排列起来。用户能够按照结构顺序来查询指定位置的对象属性。
应用场景
- 公司的结构顺序。公司存在多个部门,部门内又存在多个小组,小组内存在多个成员。
- 特殊类型的文件操作。类似于Xml类型的文本类型,其内部需要实现指定节点的增、删、改、查功能。
场景
设计一套层次关系,实现指定位置插入、删除节点的操作。
类图
组合模式- CTree: 统一的基类,定义统一的接口Add、Remove,由子类实现添加删除具体节点操作。
- CLeaf: 叶子类,其不再存在子组件的节点。
- CTrunk: 枝干类,还存在子组件的节点。
效果
客户端接口
// root
// / \ \
// / \ \
// branch1 branch2 leaf
// / \ \
// / \ \
// branch1_1 leaf1_1 leaf2_1
int main(int argc, char *argv[])
{
CTrunk theRoot("root");
CTrunk theBranch1("branch1");
CTrunk theBranch2("branch2");
CTrunk theBranch1_1("branch1_1");
CLeaf theLeaf("leaf");
CLeaf theLeaf1_1("leaf1_1");
CLeaf theLeaf2_1("leaf2_1");
theBranch1.Add(&theBranch1_1);
theBranch1.Add(&theLeaf1_1);
theBranch2.Add(&theLeaf2_1);
theRoot.Add(&theBranch1);
theRoot.Add(&theBranch2);
theRoot.Add(&theLeaf);
theRoot.ShowAllBranch(&theRoot);
//theRoot.ShowBranch();
return 0;
}
输出
branch1 branch1_1 leaf1_1
branch2 leaf2_1
leaf
具体实现
基类接口
定义对外接口,包括增加、删除节点接口。
class CTree
{
public:
CTree(): mParent(0), mFirstChild(0), mLastChild(0), mPrev(0), mNext(0)
{}
virtual ~CTree()
{}
virtual CTree* Add(CTree *pNode);
virtual int Remove(CTree *pNode);
virtual string GetName();
virtual bool IsTrunk() const;
CTree *mParent;
CTree *mFirstChild;
CTree *mLastChild;
CTree *mPrev;
CTree *mNext;
};
叶子类
叶子类无需增加子节点。
class CLeaf
{
public:
explicit CLeaf(string Name);
~CLeaf();
string GetName();
private:
string mName;
};
枝干类
枝干类需要实现增加节点接口,通过链表将各个节点连接起来。
class CTrunk : public CTree
{
public:
explicit CTrunk(string Name);
~CTrunk();
CTree* Add(CTree *pNode);
int Remove(CTree *pNode);
string GetName();
bool IsTrunk() const;
void ShowBranch();
void ShowAllBranch(CTree *p);
private:
string mName;
};
枝干类增加节点。每个枝干类内部维护一套双向链表,用于维护当前类增加的节点。
CTree* CTrunk::Add(CTree *pNode)
{
if (NULL == pNode) {
return 0;
}
if (mLastChild) {
pNode->mNext = 0;
pNode->mPrev = mLastChild;
mLastChild->mNext = pNode;
mLastChild = pNode;
}
else {
mFirstChild = mLastChild = pNode;
pNode->mPrev = 0;
pNode->mNext = 0;
}
pNode->mParent = this;
return pNode;
}
总结
-
组合模式,主要用于将相同类型的对象统一的按照树形方式管理起来,便于实现"增、删、改、查"的行为。类似Xml、部门管理的场景比较适合。
-
在使用过程中,客户端需要手动创建和释放,后面更新为自动创建回收就比较完美了。
网友评论