1、composite
(1)意图
将对象组合成树状态以表示“部分-整体”的层次结构。composite使得用户对单个对象和组合对象的使用具有一执行。
(2)结构
component为组合对中申明的接口,在适当的情况实现所有类共有接口的默认行为,声明一个接口用于访问管理componet的子组件,可选在递归结构中定义一个接口访问父组件,用于访问一个父组件,并在合适的情况下实现他。
leaf在组合中表示叶结点对象,叶结点没有子结点;在组合中定义图对象的行为。
composite定义有子组件的那些组件行为;存储子组件;在component接口实现与子组件有关的操作
client通过component接口操作组合对象的对象。
(3)适用性
想表示对象的部分-整体层次结构。
希望用户忽略组合对象与单个对象的不同,用户将统一的使用组合结构中的所有对象。
2、根据UML图写代码
1、泛华关系
从结构上来看 componet是leaf和composite的父类
2、关联关系
composite为compnet的关联关系(特殊关联 ——聚合),既在composite定义一个指向componet的指针。
3、备注
根据备注的解释,operatiaon方法解释 是要执行所有子类的operation
4、UML图的理解
通过client构建一个composite对象,通过Add增加一个“component*”类型的的结点并顺序的存在一个链表中构建一个树形结构,通过operation方法实现递归并执行子结点全部operation实现遍历并完成对应的功能。同时每一个composite都有一个专属的leaf
3、代码实现
由于时间问题为涉及析构部分,若有兴趣可自行完成。
include<iostream>
#include<list>
using namespace std;
class composite;
class componet{
public:
virtual void add(componet* p)=0;
virtual void remove( componet* p)=0;
virtual void getchild(int)=0;
virtual void operation()=0;
string name;
};
class composite:public componet{
public:
composite(string name){
this->name=name;
}
void add(componet *p){
mylist.push_back(p);
}
void remove(componet *p){
mylist.remove(p);
}
void getchild(int p){
}
void operation(){
list<componet*>::iterator it;
cout<<this->name<<endl;
for(it=mylist.begin();it!=mylist.end();it++){
(*it)->operation();//递归方式调用
}
}
private:
list<componet*> mylist;//以list实现树形结构,并提供一个componet* 指针合计形成指向一个componet*的聚合特殊关联关系
};
class leaf:public componet{
public:
leaf (string name){
this->name=name;
}
void add(componet *p){
}
void remove(componet *p){
}
void getchild(int p){
}
void operation(){
cout<<this->name<<endl;
}
};
int main(){
componet *a=new composite("总公司");//生产a结点
a->add(new leaf("总公司旗下个部门"));//将leaf放入list中
componet *b=new composite("分公司A");
a->add(b);//b放入list a的序列
b->add(new leaf("分公司A旗下各部门"));在b下面放一个list列表并存有leaf表
componet *c=new composite("分公司B");
a->add(c);
c->add(new leaf("分公司B旗下各部门"));
a->operation();
a->remove(b);
cout<<"---------------------"<<endl;
a->operation();
return 0;
}
代码实现
./a.out
总公司
总公司旗下个部门
分公司A
分公司A旗下各部门
分公司B
分公司B旗下各部门
---------------------
总公司
总公司旗下个部门
分公司B
分公司B旗下各部门
4、递归实现的过程
如果我们把代码中的a看中根结点(root)在list 下面链接过程是这样的:
a->b->c
对应的代码如下:
a->add(b)
a->add(c)
但是在结点b和c下面都各自的list结点l对应代码为:
b->add(new leaf("分公司A旗下各部门"))
c->add(new leaf("分公司 B旗下各部门"))
那么在b和c属于自己的list表中结构如下:
b->leaf
c->leaf
如果我们单存是循环root而不递归的话
for(it=mylist.begin();it!=mylist.end();it++){
cout<<(*it)->name<<endl
}
输出的结果就只有:
总公司旗下个部门
分公司A
分公司B
我们会发现分公司下的各部门不在显示,因为我们这里并没有让b结点去调用属于他自己的list表,如果我们要实现b也执行他自己list表则必须使用递归函数对应代码为:
for(it=mylist.begin();it!=mylist.end();it++){
(*it)->operation();//递归方式调用
}
具体过程
第一次 i it=mylist.begin=a.leaf() it=a.leaf() a.leaf()->operation()实现效果 总公司分公司 i++后没有数据了 进入下一层循环
第二次 it++后 it=b b-> operation()实现效果 分公司A
第三次 it++后 注意这里进入b的链表 it=mylist.begin=b.leaf() b.leaf()->operation()实现效果 分公司A i++后面没有相关的数据了,b的list循环结束进入下一层既c