购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

5.6 树

大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所示,里面的套娃就是一个套着一个的。”

图5-2 套娃

这样一堆娃娃,一个大的套一个小的,小的里面还可以套更小的,所以其组织结构为:

Top toy

-Toy

--toy

---toy

----toy

abstract class CompositeEquipment extends Equipment
{
private int i=0;
//定义一个Vector 用来存放'儿子'
private Lsit equipment=new ArrayList();
public CompositeEquipment(String name) { super(name); }
public boolean add(Equipment equipment) {
this.equipment.add(equipment);
return true;
}
public double netPrice()
{
double netPrice=0.;
Iterator iter=equipment.iterator();
for(iter.hasNext())
netPrice+=((Equipment)iter.next()).netPrice();
return netPrice;
}
public double discountPrice()
{
double discountPrice=0.;
Iterator iter=equipment.iterator();
for(iter.hasNext())
discountPrice+=((Equipment)iter.next()).discountPrice();
return discountPrice;
}
//注重这里,这里就提供用于访问自己组合体内的部件方法。
//上面dIsk 之所以没有,是因为Disk是个单独(Primitive)的元素.
public Iterator iter()
{
return equipment.iterator()
{
//重载Iterator方法
public boolean hasNext() { return i
abstract class CompositeEquipment extends Equipment
{
private int i=0;
//定义一个Vector 用来存放'儿子'
private Lsit equipment=new ArrayList();
public CompositeEquipment(String name) { super(name); }
public boolean add(Equipment equipment) {
this.equipment.add(equipment);
return true;
}
public double netPrice()
{
double netPrice=0.;
Iterator iter=equipment.iterator();
for(iter.hasNext())
netPrice+=((Equipment)iter.next()).netPrice();
return netPrice;
}
public double discountPrice()
{
double discountPrice=0.;
Iterator iter=equipment.iterator();
for(iter.hasNext())
discountPrice+=((Equipment)iter.next()).discountPrice();
return discountPrice;
}
//注重这里,这里就提供用于访问自己组合体内的部件方法。
//上面dIsk 之所以没有,是因为Disk是个单独(Primitive)的元素.
public Iterator iter()
{
return equipment.iterator()
{
//重载Iterator方法
public boolean hasNext() { return i

大B:“如果用程序来描述图5-2套娃,用设计模式的组合模式(Composite)是一个不错的主意。组合模式在GOF中定义为:组合(Composite)模式将对象以树形结构组织起来,以达成‘部分-整体’的层次结构,使得客户端对单个对象和组合对象的使用具有一致性。”

类图如图5-3所示:

图5-3 类图

大B:“可以说,组合模式是比较简单易学的设计模式,我按照其定义和规则,实现一个论坛主题,帖子的组合关系。论坛中,一个主题可以包括很多帖子 ,一个帖子还可以包括很多回复。”

关系是:

Thread

-- Thread||Message

---- Thread||Message

下面是实现文件:

using System;
using System.Collections.Generic;
using System.Text;
namespace CompositeStudy
{
public interface IThread
{
void Add(IThread thread);
void Remove(IThread thread);
void RenderContent();
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace CompositeStudy
{
public abstract class AbstractThread : IThread
{
bool _isTop;
public bool IsTop
{
get
{
return _isTop;
}
set
{
_isTop = value;
}
}
List list = new List();
public List Children
{
get
{
return list;
}
set
{
list = value;
}
}
string content = "";
public string Content
{
get
{
return content;
}
set
{
content = value;
}
}
public void Add(IThread thread)
{
list.Add(thread);
}
public void Remove(IThread thread)
{
list.Remove(thread);
}
public abstract void RenderContent();
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace CompositeStudy
{
public class Thread : AbstractThread
{
public override void RenderContent()
{
//输出自己的Contetn
Console.WriteLine("Thread:"+this.Content);
foreach (IThread t in Children)
{
t.RenderContent();
}
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace CompositeStudy
{
public class Message:AbstractThread
{
public override void RenderContent()
{
Console.WriteLine("Message:" + this.Content);
foreach (IThread t in Children)
{
t.RenderContent();
}
}
}
}

工厂类为:

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
namespace CompositeStudy
{
/**//// 













/// 工厂类 /// 
/// 工厂类
public class ThreadFactory
{
DataTable table = new DataTable();
public ThreadFactory()
{
table.Columns.Add("content");
table.Columns.Add("IsTop");
table.Columns.Add("IsMessage");
table.Columns.Add("ID");
table.Columns.Add("ParentID");
DataRow row = 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);
}
public List GetTopThreads()
{
List list = new List();
DataRow[] rows = table.Select("IsTop = true");
foreach (DataRow row in rows)
{
Thread t = new Thread();
t.Content = row["content"].ToString();
t.IsTop = true;
DataRow[] cs = table.Select("ParentID="+Convert.ToInt32(row["ID"]));
foreach (DataRow r in cs)
{
if (Convert.ToBoolean(r["IsMessage"]))
{
Message m = new Message();
m.Content = r["content"].ToString();
m.IsTop = false;
t.Add(m);
}
else
{
Thread tt = new Thread();
tt.Content = r["content"].ToString();
tt.IsTop = false;
t.Add(tt);
}
}
list.Add(t);
}
return list;
}
}
}

客户端调用方法为:

using System;
using System.Collections.Generic;
using System.Text;
namespace CompositeStudy
{
class Program
{
static void Main(string[] args)
{
ThreadFactory factory = new ThreadFactory();
List threads = factory.GetTopThreads();
foreach(IThread t in threads)
{
t.RenderContent();
}
Console.Read();
}
}
}

类关系图如图5-4所示:

图5-4 类关系图

输结果为: WHB3gQApF3+Sl1ZZ2HmlGux53v4VTeKGXZ9u0ESePeXz8MOs8OlxA0YQwP1PtvAW

点击中间区域
呼出菜单
上一章
目录
下一章
×