.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
這樣我們在實際應用中就不用再去實現一個自定義委託了,直接用這個泛型委託就可滿足我們應用事件的需要。
3、 一個負責通知事件訂閱者的事件源類(類似於觀察者模式中的具體主題ConcreteSubject),這個類包含一個事件成員,負責向外提供事件的訂閱和註銷接口,並保存他們的狀態;一個負責引發事件的方法以通知所有這個事件的訂閱者,這個方法需要是一個受保護的虛擬方法,並且是以On開頭以事件名字結尾,並且接受一個類型為System.Eventargs(或子類)的參數。如定義一個事件成員:
public event EventHandler
那麼這個方法應為:
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
//負責引發事件的方法
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)!