大话设计模式
字体: 16 + -

第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();

}

}

}