首頁  >  文章  >  後端開發  >  C#對觀察者(Observer)模式的支持(二)

C#對觀察者(Observer)模式的支持(二)

黄舟
黄舟原創
2016-12-21 14:56:551218瀏覽

        .Net為我們應用事件定義了標準的模式,我們在應用過程中應遵守定義事件的規則。一個標準的事件模式包括四個面向的內容:

1、  一個繼承自System.EventArgs類型的事件訊息類,而這個類別的名稱以EventArgs結尾,如SendMailEventArgs,這個類別負責保存事件來源發送給事件監聽者的信息。如果事件來源不需要傳遞額外的訊息給事件監聽者訊息,可以直接使用EventArgs.Empty,這時我們就不用再去定義自己的事件訊息類別了。

2、  定義事件時所使用的委託(類似觀察者模式中的抽象主題Subject和抽象觀察者Observer),這個委託回傳型別為void,有兩個參數,第一個參數型別為Object,第二個為System.EventArgs或它的子類,名字應以EventHandler結尾,如:

public  delegate void XxxEventHandler(object sender,SendMailEventArgs e);.net框架為我們定義了一個符合事件規範的泛型委託



















System.EventHandler(Object sender , TeventArgs e) where TeventArgs:EventArgs;

這樣我們在實際應用中就不用再去實現一個自定義委託了,直接用這個泛型委託就可滿足我們應用事件的需要。

3、  一個負責通知事件訂閱者的事件源類(類似於觀察者模式中的具體主題ConcreteSubject),這個類包含一個事件成員,負責向外提供事件的訂閱和註銷接口,並保存他們的狀態;一個負責引發事件的方法以通知所有這個事件的訂閱者,這個方法需要是一個受保護的虛擬方法,並且是以On開頭以事件名字結尾,並且接受一個類型為System.Eventargs(或子類)的參數。如定義一個事件成員:

public  event EventHandler  SendMail;

那麼這個方法應為:

PRotected virtual void OnSendMail(SendMailArgs es e
PRotected virtual void OnSendMail(SendMailArgs es ehamm};期望事件的方法,估且叫做觸發器吧。

這個方法負責實例化一個事件訊息類,呼叫引發事件的方法OnXxx,並將事件訊息實例傳遞過去。

4、  事件監聽者類(類似於觀察者模式中的具體觀察者ConcreteObserver),用來監聽事件源發出的消息,這個類用來定義和事件相兼容的方法,格式為返回值為void,有兩個參數,第一個參數類型為Object,第二個為對應的事件訊息類別。例:protected void Phone_SendMail(Object sender,EventArgs e)…;

下面改寫上篇文章中的郵件發送系統:

首先定義一個事件訊息類,這個類別負責保存向設備發送的訊息。

view plaincopy to clipboardprint?
public class SendMailEventArgs:EventArgs   
    {   
    Message;   
        public SendMailEventArgs(string message)   
        {  
        }   
    }  
public class SendMailEventArgs:EventArgs
    {
        //只讀的資訊欄位
        
        {
            this.Message = message;
     plaincopy to clipboardprint?🎜class MailManager   🎜    {   🎜        //郵件        {   🎜            set  🎜     ess = value;   🎜}   
            get  
            {  essage();   
            }   
        }        public event EventHandler SendMail;   
        //負責引發事件的方法   
        protected virtual void OnSendMial(SendMailEventArgs e)   
     EventArgs> sendMail=SendMail;   
            if (sendMail != null)   🎠         //通知所有訂閱者   
                sendMail(this, e);   
}   
        }   
        //負責將外部調用轉化為事件   
        public void SendToMail()   
        {   
            if (String.IsNullOrEmpty(MailMess.Subject) || string.IsNullOrEmpty(MailMess.Body))   
            {   
                Console.WriteLine( "郵件寄送失敗!");   
            }   
                          Console.WriteLine("發送郵件:{0}",MailMess.Subject);    
                SendMailEventArgs sendMailEventArgs = new SendMailEventArgs(MailMess.Subject);   
                //已通知所有事件訂閱者   EventArgs);   
            }   
        }       //郵件
        public System.Net.Mail.MailMessage MailMess
{
            set
            {
         }
            get
            { 
}
        }
        /使用.net架構中提供的泛型委託定義一個事件
       
        protected virtual void OnSendMial(SendMailEventArgs e)
        { 
  > sendMail=SendMail;
            if (sendMail != null)
           
                sendMail(this, e);
           
        public void SendToMail()
        {
            if (String.IsNullOrEmpty(MailMess.Subject) || string.IsNullOrEmpty(MailMess.Body))
            {
                Console.WriteLine("郵件發送失敗!");
            }
            else
            {
                Console.WriteLine( "寄信:{0}", MailMess.Subject);
                //以郵件的Subject實例化一個事件資訊類SendMailEventArgs(MailMess.Subject);
                //已通知所有事件訂閱者
      OnSendMial(sendMailEventArgs);
            }
        }
    
    {  
        #region SendHandler 成員   
  
       {   
            Console. WriteLine("手機信息:{0}", e.Message);   
        }  

        #endregion   
    }   
public class RTX   
    {  
        #region SendHandler 成員   
  
        public void SendMessage(object sender,SendMailEventArgs e)   
        {   
Console.WriteLine("RTX訊息:{0}", e.Message);   
        }  

        {
        #region SendHandler 成員

        public void SendMessage(object 
Console.WriteLine("手機資訊:{0}", e.Message);
        }

        #    #region SendHandler 成員

        public void SendMessage(object sender,SendMailEventArgs e)
{
            Console.WriteLine("RTX訊息:{0}", e.Message);
       


下面是客戶端的呼叫

view plaincopy to clipboardprint?
class Program   
    {   
static void Main(string[] args)   
        {   
           new MailManager();   
            //為Mail中新增主題與內容   
            mailManager. MailMess.Body = "觀察者模式的學習。";   
            mailManager.SendMail+=new MobilePhone().SendMessage =new RTX().SendMessage;//註冊RTX通知   
              mail的Manager. SendToMail();//寄送郵件   
              Console.WriteLine("按任鍵繼續…");           }   
    }  

 以上是C#觀察者(Observer)模式的支持(二)的內容,更多相關內容請關注PHP中文網(www.php.cn)! 



陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn