窥视设计模式之组合模式(composite)
经常使用Control,会发现Control有Controls的属性,而Controls集合包含的还是一个Control,类似的还有XmlNode.他们都有一个共有的特性,数据结构都是树行结构,什么是树形模式呢?
树(Tree)是n(n≥0)个结点的有限集T,T为空时称为空树,否则它满足如下两个条件:
(1) 有且仅有一个特定的称为根(Root)的结点;
(2) 其余的结点可分为m(m≥0)个互不相交的子集Tl,T2,…,Tm,其中每个子集本身又是一棵树,并称其为根的子树(SubTree)。上面给出的递归定义刻画了树的固有特性:一棵非空树是由若干棵子树构成的,而子树又可由若干棵更小的子树构成。而这里的子树可以是叶子也可以是分支。
先看下一幅图,里面的套娃就是一个套着一个的
这样一堆娃娃,一个大的套一个小的,小的里面还可以套更小的,所以其组织结构为:
Top Toy
- Toy
-- toy
----toy
----toy
如果用程序来描述上图,用设计模式的组合模式(Composite)是一个不错的主意
组合模式在GOF中定义为: 组合(Composite)模式将对象以树形结构组织起来,以达成“部分-整体”的层次结构,使得客户端对单个对象和组合对象的使用具有一致性。
类图为:
可以说,组合模式是比较简单易学的设计模式,我按照其定义和规则,实现一个论坛主题,帖子的组合关系
论坛中,一个主题可以包括很多帖子 ,一个帖子还可以包括很多回复。关系是:
Thread
-- Thread||Message
-- Thread||Message
下面是实现文件:
工厂类为:
using System;2
using System.Collections.Generic;3
using System.Text;4
using System.Data;5

6
namespace CompositeStudy7
{8
/// <summary>9
/// 工厂类10
/// </summary>11
/// <remarks>工厂类</remarks>12
public class ThreadFactory13
{14
DataTable table = new DataTable();15
public ThreadFactory()16
{17
table.Columns.Add("content");18
table.Columns.Add("IsTop");19
table.Columns.Add("IsMessage");20
table.Columns.Add("ID");21
table.Columns.Add("ParentID");22

23
DataRow row = table.NewRow();24
row["content"] = "test";25
row["IsTop"] = false; 26
row["IsMessage"] = false;27
row["ID"] = 1;28
row["ParentID"] = 0;29
table.Rows.Add(row);30

31
row = table.NewRow();32
row["content"] = "test1";33
row["IsTop"] = true;34
row["IsMessage"] = false;35
row["ID"] = 0;36
row["ParentID"] = -1;37
table.Rows.Add(row);38

39
row = table.NewRow();40
row["content"] = "test2";41
row["IsTop"] = false;42
row["IsMessage"] = true;43
row["ID"] = 2;44
row["ParentID"] = 0;45
table.Rows.Add(row);46

47
row = table.NewRow();48
row["content"] = "test3";49
row["IsTop"] = false;50
row["IsMessage"] = true;51
row["ID"] = 3;52
row["ParentID"] = 0;53
table.Rows.Add(row);54
}55
public List<IThread> GetTopThreads()56
{57
List<IThread> list = new List<IThread>();58
DataRow[] rows = table.Select("IsTop = true");59
foreach (DataRow row in rows)60
{61
Thread t = new Thread();62
t.Content = row["content"].ToString();63
t.IsTop = true;64
DataRow[] cs = table.Select("ParentID="+Convert.ToInt32(row["ID"]));65
foreach (DataRow r in cs)66
{67
if (Convert.ToBoolean(r["IsMessage"]))68
{69
Message m = new Message();70
m.Content = r["content"].ToString();71
m.IsTop = false;72
t.Add(m);73
}74
else75
{76
Thread tt = new Thread();77
tt.Content = r["content"].ToString();78
tt.IsTop = false;79
t.Add(tt);80
}81
}82
list.Add(t);83
}84
return list;85
}86
}87
}88

客户端调用方法为:
using System;2
using System.Collections.Generic;3
using System.Text;4

5
namespace CompositeStudy6
{7
class Program8
{9
static void Main(string[] args)10
{11
ThreadFactory factory = new ThreadFactory();12
List<IThread> threads = factory.GetTopThreads();13
foreach(IThread t in threads)14
{15
t.RenderContent();16
}17
Console.Read();18
}19
}20
}21

类关系图:
输结果为:
通过该事例的调用,就可以知道,组合模式的好处有:
1) 使客户端调用简单,客户端可以一致的使用组合结构或其中单个对象,用户就不必关心自己处理的是单个对象还是整个组合结构,这就简化了客户端代码。
2) 更容易在组合体内加入对象部件. 客户端不必因为加入了新的对象部件而更改代码。这一点符合开闭原则的要求,对系统的二次开发和功能扩展很有利!
出处:http://jillzhang.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。



浙公网安备 33010602011771号