窺視設計模式之組合模式(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號