Iron之觀察者
引言
上一篇說的職責鏈模式,很有意思的一個模式,今天這個模式也是很有意思的一個模式,還是不啰嗦了直接進入主題吧。
場景介紹:在上一遍中說到用到部件檢測,很巧妙的讓調用者和處理者解耦了(沒有看過上篇的文章也沒關系,只是劇情是要接著發展的),要把部件拿去檢測是要讓個人來盯著看呢?還是部件生產好了自動就被拿去檢測了呢?毋庸置疑必須是自動化的。
看一下部件的結構
1 /// <summary>
2 /// 部件
3 /// </summary>
4 public class ComponentModel
5 {
6 public string Name { get; set; }
7 public int Value
8 {
9 get
10 {
11 return 5;
12 }
13 }
14
15 }
這個部件還是上一篇的部件,沒有做任何改動。只是示例,為了讓沒看過上一篇的朋友知道。
按照場景裡所要求的,定義了下面的兩個類型,ComponentModelFactory類型,ComponentModel類型工廠負責生產ComponentModel部件,並且在完成時通知要另外處理部件的對象。
ExecutionCheck類型,就是要要被通知到的對象,它等待著別人告訴它 “有部件生產好了,需要被你送去檢測”,不會它會很無聊。
1 /// <summary>
2 /// 示例ComponentModel類型工廠 生產了ComponentModel 通知ExecutionCheck對象去檢測
3 /// </summary>
4 public class ComponentModelFactory
5 {
6 public static ComponentModel ComModelFactory()
7 {
8 return new ComponentModel();
9 }
10 }
11 /// <summary>
12 /// 送ComponentModel對象去檢測
13 /// </summary>
14 public class ExecutionCheck
15 {
16 public void ComponentModelCheck(ComponentModel comModel)
17 {
18 //送去執行檢測
19 //或者是一些其他操作
20 }
21 }
來看看調用代碼:
1 ExecutionCheck executionCheck = new ExecutionCheck(); 2 executionCheck.ComponentModelCheck(ComponentModelFactory.ComModelFactory()); 3 executionCheck.ComponentModelCheck(ComponentModelFactory.ComModelFactory()); 4 executionCheck.ComponentModelCheck(ComponentModelFactory.ComModelFactory());
似乎是解決了問題,但是結果糟透了,雖然executionCheck很高興,因為它有活干了,我只能以這樣的方式去通知executionCheck,或許有人說修改下ComponentModelFactory類型會好一點,我知道是這樣的:
1 public class ComponentModelFactory
2 {
3 public static ComponentModel ComModelFactory()
4 {
5 return new ComponentModel();
6 }
7 public void PastMessage(ComponentModel componentModel,ExecutionCheck executionCheck)
8 {
9 executionCheck.ComponentModelCheck(componentModel);
10 }
11 }
調用代碼則調整為:
1 ComponentModelFactory componentModelFactory = new ComponentModelFactory(); 2 ExecutionCheck executionCheck=new ExecutionCheck(); 3 componentModelFactory.PastMessage(ComponentModelFactory.ComModelFactory(), executionCheck);
這樣的結果,調用方式沒問題了,可是ComponentModelFactory類型的內部居然有著這樣高的耦合,無法忍受,必須得找出一種方式或者模式來解決這樣的難題,不然寢食難安!!!!
定義對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知並被自動更新。
——Gof
按照模式的定義重新來過(會有點不一樣的地方中心思想不變),先對ExecutionCheck 類型進行抽象
1 /// <summary>
2 /// 抽象的ExecutionCheck(抽象觀察者)
3 /// </summary>
4 public abstract class ABSExecutionCheck
5 {
6 public abstract void ComponentModelCheck(ComponentModel comModel);
7 }
8
9 /// <summary>
10 /// 送ComponentModel對象去檢測(觀察者)
11 /// </summary>
12 public class ExecutionCheck:ABSExecutionCheck
13 {
14 public override void ComponentModelCheck(ComponentModel comModel)
15 {
16 //送去執行檢測
17 //或者是一些其他操作
18 }
19 }
然後再對ComponentModelFactory進行改造,並且抽象它。
1 /// <summary>
2 /// 抽象目標
3 /// </summary>
4 public abstract class ABSComponentModelFactory
5 {
6 protected ABSExecutionCheck absExecutionCheck;
7 public abstract void RegisterABSExecutionCheck(ABSExecutionCheck executionCheck);
8 public abstract void ClearABSExecutionCheck();
9 public abstract void PastMessage(ComponentModel componentModel);
10 }
ABSComponentModelFactory類型是要讓ComponentModelFactory類型實現的,從這裡可以看出是遵循設計原則的面對抽象編程的,當然了最後一個PastMessage函數忽略掉,現在來看一下實現了抽象目標ABSComponentModelFactory的ComponentModelFactory(具體目標)的實現。
1 /// <summary>
2 /// 示例ComponentModel類型工廠 生產了ComponentModel 通知ExecutionCheck對象去檢測 (具體目標)
3 /// </summary>
4 public class ComponentModelFactory:ABSComponentModelFactory
5 {
6 public static ComponentModel ComModelFactory()
7 {
8 return new ComponentModel();
9 }
10
11 public override void RegisterABSExecutionCheck(ABSExecutionCheck executionCheck)
12 {
13 absExecutionCheck = executionCheck;
14 }
15
16 public override void ClearABSExecutionCheck()
17 {
18 absExecutionCheck = null;
19 }
20 public override void PastMessage(ComponentModel componentModel)
21 {
22 absExecutionCheck.ComponentModelCheck(componentModel);
23 }
24 }
現在再來看一下調用的代碼:
1 ABSExecutionCheck executionCheck = new ExecutionCheck(); 2 ABSComponentModelFactory componentModelFactory = new ComponentModelFactory(); 3 componentModelFactory.RegisterABSExecutionCheck(executionCheck); 4 componentModelFactory.PastMessage(ComponentModelFactory.ComModelFactory());
這樣就比較穩固了,在第一行new ExecutionCheck()的地方可以動態注入,和最後行的工廠生產對象一樣。因為這裡只是示例就不會很嚴謹。 還有要說的就是定義中是一對多,這樣可以修改ABSComponentModelFactory類型中的字段,修改為集合類型就可以了。 把對應的實現類也適當的修改一下就可以了。
觀察者就講到這裡。下一篇是外觀,敬請期待。
作者:金源
出處:http://www.cnblogs.com/jin-yuan/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面