標籤:name 結果 param bsp 資訊 依賴 amd 好的 系統
1、觀察者模式概念
觀察者模式定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象,這個主題對象在狀態發生變化時,會通知所有觀察者對象,使它們能夠自動更新自己的行為。
觀察者模式實現了展示層和資料邏輯層的分離,並定義了穩定的更新訊息傳遞機制,並抽象了更新介面,使得可以有各種各樣不同的展示層,即觀察者。
觀察者模式在被觀察者和觀察者之間建立了一個抽象的耦合,被觀察者並不知道任何一個具體的觀察者,只是儲存著抽象觀察者的列表,每個具體觀察者都符合一個抽象觀察者的介面。
2、業務情境
類比管理系統推送最新訊息給對應使用者,採用觀察者模式將很好的類比此類情境,使發行者與訂閱者之間實現解耦。
3、實戰
3.1 定義實體物件
定義訂閱者實體類
namespace SubscriberDesignWithRedis.Model{ public class User { /// <summary> /// 使用者id /// </summary> public string userId { get; set; } /// <summary> /// 使用者名稱稱 /// </summary> public string userName { get; set; } }}
此處List<User> 用於儲存訂閱者列表
namespace SubscriberDesignWithRedis.Model{ [Serializable] public class Information { /// <summary> /// 發行者集合 /// </summary> public List<User> userList{ get; set; } /// <summary> /// 訊號 /// </summary> public string signal { get; set; } /// <summary> /// 訊息 /// </summary> public string info { get; set; } }}
3.2 發行者
/// <summary> /// 門戶發布資訊 /// </summary> public class PortalPublish { /// <summary> /// 定義委託方法,充當訂閱者介面 /// </summary> /// <param name="obj"></param> public delegate void NotifySubscribeEventHandler(object obj); /// <summary> /// 發布訊息內部類 /// </summary> public class PublishInfo { public NotifySubscribeEventHandler notifyEvent; /// <summary> /// 訊息實體 /// </summary> public Information Information { get; set; } /// <summary> /// 重載構造器 /// </summary> /// <param name="information">訊息實體</param> public PublishInfo(Information information) { this.Information = information; } /// <summary> /// 新增 /// </summary> /// <param name="ob"></param> public void AddSubscribe(NotifySubscribeEventHandler ob){ notifyEvent += ob; } /// <summary> /// 刪除 /// </summary> /// <param name="ob"></param> public void RemoveSubscribe(NotifySubscribeEventHandler ob){ notifyEvent -= ob; } /// <summary> /// 更新( 使用lamda運算式 ) /// </summary> public void Update() => notifyEvent?.Invoke(this); } public class PortalPublishInfo : PublishInfo { public PortalPublishInfo(Information information) : base(information) { } } }
3.3 訂閱者
namespace SubscriberDesignWithRedis{ public class Subscriber { public string Name { get; set; } public Subscriber(string name) { this.Name = name; } /// <summary> /// 接收 /// </summary> /// <param name="obj"></param> public void Recevie(object obj) { PortalPublish.PortalPublishInfo portalPublishInfo = obj as PortalPublish.PortalPublishInfo; if(portalPublishInfo != null) { Console.WriteLine("Notified {0} of {1}‘s " + "Info is :{2}", Name,
portalPublishInfo.Information.signal, portalPublishInfo.Information.info); } } }}
3.4 測試類別
namespace SubscriberDesignWithRedis{ class Program { static void Main(string[] args) { //類比訂閱者的集合 List<User> userList = new List<User>() { new User() { userId = "1", userName = "ozil" }, new User() { userId = "2",userName = "Alexis"} }; //定義發布資料 Information information = new Information() { signal = "Publish Info", info = "this is a new information for each client", userList = userList }; PortalPublishInfo portalPublish = new PortalPublishInfo(information); Console.WriteLine("添加訂閱者"); //迴圈訂閱者列表,將訊息發送給具體訂閱者 foreach (User user in userList) { Subscriber client = new Subscriber(user.userName); portalPublish.AddSubscribe(new NotifySubscribeEventHandler(client.Recevie)); } //執行事件 portalPublish.Update(); Console.WriteLine("--------------------------------------------"); Console.WriteLine("移除訂閱者"); foreach (User user in userList) { Subscriber client = new Subscriber(user.userName); portalPublish.RemoveSubscribe(new NotifySubscribeEventHandler(client.Recevie)); } //執行事件 portalPublish.Update(); Console.ReadLine(); } }}
4、運行結果
c#設計模式(3)—— 利用觀察者模式類比推送訊息