第37章
大b:“经常使用control,你会发现control有controls的属性,而controls集合包含的还是一个control,类似的还有xmlnode。他们都有一个共有的特性,数据结构都是树行结构。”
小a:“什么是树形模式呢?”
大b:“树(tree)是n(n≥0)个结点的有限集t,t为空时称为空树,否则它满足如下两个条件:1、有且仅有一个特定的称为根(root)的结点;2、其余的结点可分为m(m≥0)个互不相交的子集tl,t2……,tm,其中每个子集本身又是一棵树,并称其为根的子树(subtree)。”
大b:“上面给出的递归定义刻画了树的固有特性:一棵非空树是由若干棵子树构成的,而子树又可由若干棵更小的子树构成。而这里的子树可以是叶子也可以是分支。先看下一幅图,里面的套娃就是一个套着一个的。”图5-2套娃这样一堆娃娃,一个大的套一个小的,小的里面还可以套更小的,所以其组织结构为:
toptoy
toy
——toy
——toy
——toy
大b:“如果用程序来描述套娃,用设计模式的组合模式(composite)是一个不错的主意。组合模式在gof中定义为:组合(composite)模式将对象以树形结构组织起来,以达成‘部分-整体’的层次结构,使得客户端对单个对象和组合对象的使用具有一致性。”
大b:“可以说,组合模式是比较简单易学的设计模式,我按照其定义和规则,实现一个论坛主题,帖子的组合关系。论坛中,一个主题可以包括很多帖子,一个帖子还可以包括很多回复。”
关系是:
thread
——thread||message
——thread||message
下面是实现文件:
usingsystem;
usingsystem.collections.generic;
usingsystem.text;
namespacecompositestudy
{
publicinterfaceithread
{
voidadd(ithreadthread);
voidremove(ithreadthread);
voidrendercontent();
}
}
usingsystem;
usingsystem.collections.generic;
usingsystem.text;
namespacecompositestudy
{
publicabstractclassabstractthread:ithread
{
boolistop;
publicboolistop
{
get
{
returnistop;
}
set
{
istop=value;
}
}
list《ithread》list=newlist《ithread》();
publiclist《ithread》children
{
get
{
returnlist;
}
set
{
list=value;
}
}
stringcontent=;
publicstringcontent
{
get
{
returncontent;
}
set
{
content=value;
}
}
publicvoidadd(ithreadthread)
{
list.add(thread);
}
publicvoidremove(ithreadthread)
{
list.remove(thread);
}
publicabstractvoidrendercontent();
}
}
usingsystem;
usingsystem.collections.generic;
usingsystem.text;
namespacecompositestudy
{
publicclassthread:abstractthread
{
publicoverridevoidrendercontent()
{
//输出自己的。
console.writeline(thread:+this.content);
foreach(ithreadtinchildren)
{
t.rendercontent();
}
}
}
}
usingsystem;
usingsystem.collections.generic;
usingsystem.text;
namespacecompositestudy
{
publicclassmessage:abstractthread
{
publicoverridevoidrendercontent()
{
console.writeline(message:+this.content);
foreach(ithreadtinchildren)
{
t.rendercontent();
}
}
}
}
工厂类为:
usingsystem;
usingsystem.collections.generic;
usingsystem.text;
usingsystem.data;
namespacecompositestudy
{
/**////《summary》
///工厂类
///《/summary》
///《remarks》工厂类《/remarks》
publicclassthreadfactory
{
datatabletable=newdatatable();
publicthreadfactory()
{
table.columns.add(“content”);
table.columns.add(“istop”);
table.columns.add(“ismessage”);
table.columns.add(“id”);
table.columns.add(“parentid”);
datarowrow=table.newrow();
row[“content”]=“test”;
row[“istop”]=false;
row[“ismessage”]=false;
row[“id”]=1;
row[“parentid”]=0;
table.rows.add(row);
row=table.newrow();
row[“content”]=“test1”;
row[“istop”]=true;
row[“ismessage”]=false;
row[“id”]=0;
row[“parentid”]=-1;
table.rows.add(row);
row=table.newrow();
row[“content”]=“test2”;
row[“istop”]=false;
row[“ismessage”]=true;
row[“id”]=2;
row[“parentid”]=0;
table.rows.add(row);
row=table.newrow();
row[“content”]=“test3”;
row[“istop”]=false;
row[“ismessage”]=true;
row[“id”]=3;
row[“parentid”]=0;
table.rows.add(row);
}
publiclist《ithread》gettopthreads()
{
list《ithread》list=newlist《ithread》();
datarow[]rows=table.select(“istop=true”);
foreach(datarowrowinrows)
{
threadt=newthread();
t.content=row[“content”].tostring();
t.istop=true;
datarow[]cs=table.select(“parentid=”+convert.toint32(row[“id”]));
foreach(datarowrincs)
{
if(convert.toboolean(r[“ismessage”]))
{
messagem=newmessage();
m.content=r[“content”].tostring();
m.istop=false;
t.add(m);
}
else
{
threadtt=newthread();
tt.content=r[“content”].tostring();
tt.istop=false;
t.add(tt);
}
}
list.add(t);
}
returnlist;
}
}
}
客户端调用方法为:
usingsystem;
usingsystem.collections.generic;
usingsystem.text;
namespacecompositestudy
{
classprogram
{
staticvoidmain(string[]args)
{
threadfactoryfactory=newthreadfactory();
list《ithread》threads=factory.gettopthreads();
foreach(ithreadtinthreads)
{
t.rendercontent();
}
console.read();
}
}
}