C#設計模式之觀察者


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類型中的字段,修改為集合類型就可以了。 把對應的實現類也適當的修改一下就可以了。

 

觀察者就講到這里。下一篇是外觀,敬請期待。

 

         


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM