.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<TEventArgs>(Object sender , TeventArgs e) where TeventArgs:EventArgs;
這樣我們在實際應用中就不用再去實現一個自訂委託了,直接用這個泛型委派就可滿足我們應用事件的需要。
3、 一個負責通知事件訂閱者的事件來源類(類似於觀察者模式中的具體主題ConcreteSubject),這個類包含一個事件成員,負責向外提供事件的訂閱和登出介面,並儲存他們的狀態;一個負責引發事件的方法以通知所有這個事件的訂閱者,這個方法需要是一個受保護的虛方法,並且是以On開頭以事件名字結尾,並且接受一個類型為System.Eventargs(或子類)的參數。如定義一個事件成員:
public event EventHandler<SendMailEventArgs> SendMail;
那麼這個方法應為:
PRotected virtual void OnSendMail(SendMailEventArgs e){};
還有一個負責將外部調用或輸入轉化為期望事件的方法,估且叫做觸發器吧。
這個方法負責執行個體化一個事件訊息類,調用引發事件的方法OnXxx,並將事件訊息執行個體傳遞過去。
4、 事件監聽者類(類似於觀察者模式中的具體觀察者ConcreteObserver),用來監聽事件來源發出的訊息,這個類用來定義和事件相相容的方法,格式為傳回值為void,有兩個參數,第一個參數類型為Object,第二個為相應的事件訊息類。例:protected void Phone_SendMail(Object sender,EventArgs e)……;
下面改寫上篇文章中的郵件發送系統:
首先定義一個事件訊息類,這個類負責儲存向裝置發送的訊息。
view plaincopy to clipboardprint?
public class SendMailEventArgs:EventArgs
{
//唯讀資訊欄位
public readonly string Message;
public SendMailEventArgs(string message)
{
this.Message = message;
}
}
public class SendMailEventArgs:EventArgs
{
//唯讀資訊欄位
public readonly string Message;
public SendMailEventArgs(string message)
{
this.Message = message;
}
}
事件來源類.
view plaincopy to clipboardprint?
class MailManager
{
//郵件
public System.Net.Mail.MailMessage MailMess
{
set
{
MailMess = value;
}
get
{
return new System.Net.Mail.MailMessage();
}
}
//用.net架構提供的泛型委派定義一個事件
public event EventHandler<SendMailEventArgs> SendMail;
//負責引發事件的方法
protected virtual void OnSendMial(SendMailEventArgs e)
{
EventHandler<SendMailEventArgs> 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 sendMailEventArgs = new SendMailEventArgs(MailMess.Subject);
//通知所有事件訂閱者
this.OnSendMial(sendMailEventArgs);
}
}
}
class MailManager
{
//郵件
public System.Net.Mail.MailMessage MailMess
{
set
{
MailMess = value;
}
get
{
return new System.Net.Mail.MailMessage();
}
}
//用.net架構提供的泛型委派定義一個事件
public event EventHandler<SendMailEventArgs> SendMail;
//負責引發事件的方法
protected virtual void OnSendMial(SendMailEventArgs e)
{
EventHandler<SendMailEventArgs> 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 sendMailEventArgs = new SendMailEventArgs(MailMess.Subject);
//通知所有事件訂閱者
this.OnSendMial(sendMailEventArgs);
}
}
}
事件監聽類
view plaincopy to clipboardprint?
class MobilePhone
{
#region SendHandler 成員
public void SendMessage(object sender,SendMailEventArgs e)
{
Console.WriteLine("手機資訊:{0}", e.Message);
}
#endregion
}
public class RTX
{
#region SendHandler 成員
public void SendMessage(object sender,SendMailEventArgs e)
{
Console.WriteLine("RTX資訊:{0}", e.Message);
}
#endregion
}
class MobilePhone
{
#region SendHandler 成員
public void SendMessage(object sender,SendMailEventArgs e)
{
Console.WriteLine("手機資訊:{0}", e.Message);
}
#endregion
}
public class RTX
{
#region SendHandler 成員
public void SendMessage(object sender,SendMailEventArgs e)
{
Console.WriteLine("RTX資訊:{0}", e.Message);
}
#endregion
}
下面是用戶端的調用
view plaincopy to clipboardprint?
class Program
{
static void Main(string[] args)
{
//事件監聽源執行個體
MailManager mailManager = new MailManager();
//為Mail添加主題和內容
mailManager.MailMess.Subject = "通知";
mailManager.MailMess.Body = "觀察者模式的學習。";
mailManager.SendMail+=new MobilePhone().SendMessage;//註冊手機通知
mailManager.SendMail+=new RTX().SendMessage;//註冊RTX通知
mailManager.SendToMail();//發送郵件
Console.WriteLine("按任意鍵繼續……");
Console.ReadKey();
}
}
以上就是C#對觀察者(Observer)模式的支援(二)的內容,更多相關內容請關注topic.alibabacloud.com(www.php.cn)!