使用者新增bug回報後或需求單,如果不主動登入網頁時就永遠無法知道誰回報了BUG,無法有主動通知的概念,想要有一個有主動通知的提醒功能,於是想到了觀察者的模式,以後不論有新的系統需要主動偵測時,在新增物件後,自動有擴充效果。
情境1:
當接收的人員已經按下確定後,警告視窗不需提醒,如果A人員已經看過並按下確定後,無法再彈出,但B人員尚未看過,仍不斷跳出提醒,確定每位人員都能看到bug回報。
情境3: 為了有擴充的功能,採用觀察者的樣式,
觀察者 (Observer) 與被觀察者 (Observable) 之間採用鬆偶合 (loose-coupling/鬆綁) 的方式結合。因為雙方有實踐特定介面,因此不用知道彼此的細節。
本案例中testBugObserver和releaseBugObserver有各自邏輯檢查是否有該登入者尚未讀取,所以在observer的父類別,訂出抽象類別的方法findNoRead ,由繼承的子類別覆寫findNoRead的邏輯,父類別SupperSubject的attach負責把加入繼承supperObserver的物件,再由父類別的SupperSubject的listAllNoRead將所有繼承supperObserver的物件的findNoRead去搜尋未讀的資料。
程式範例 觀察者模式又稱(發布/訂閱)模式
父類別:訂閱者的角色
public abstract class supperObserver
{
public abstract IList<viewData> findNoRead(string userID);
}
子類別:繼承父類別訂閱者
public class testBugObserver : supperObserver
{
public override IList<viewData> findNoRead(string userID)
{
entityNotifyData entityModel = new entityNotifyData();
IList<viewData> liData = entityModel.liBugNoReadTestData(userID); //讀取資料
return liData.ToList();
}
}
子類別:繼承父類別訂閱者
public class releaseBugObserver : supperObserver
{
public override IList<viewData> findNoRead(string userID)
{
entityNotifyData entityModel = new entityNotifyData();
IList<viewData> liData = entityModel.liBugNoReadReleaseData(userID); //讀取資料
return liData.ToList();
}
}
|
子類別繼承父類別supperObserver,覆寫父類別的findNoRead(string
userID),讓物件有各自不同的邏輯,後續也容易可以擴充新的物件。
public abstract class supperSubject
{
/// 登入者的帳號
public string userID { get; set; }
/// 訂閱者們
private IList<supperObserver> liObservers = new List<supperObserver>();
public void attach(supperObserver Observer)
{
liObservers.Add(Observer);
}
/// 取回所有未讀資料
public List<viewData> listAllNoRead()
{
List<viewData> liViewData = new List<viewData>();
foreach (supperObserver observer in liObservers)
{
// 物件本身的findNoRead
有各自的邏輯,以達到擴充的效果
liViewData.AddRange(observer.findNoRead(userID));
}
return liViewData;
}
}
public class subject : supperSubject
{
}
|
觀察者和被觀察者的父類別先定義好彼此的關係,父類別的supperSubject 有兩個方法attach 和listAllNoRead。
l attach :由繼承supperSubject 的子類別用attach的方式加入有繼承supperObserver 的物件到父類別IList<supperObserver>
liObservers陣列集合
l listAllNoRead : 由繼承supperSubject 的子類別用listAllNoRead 逐一把陣列集合中的物件,呼叫物件覆寫父類別supperObserver的findNoRead
private void
timer1_Tick(object sender, EventArgs e)
{
_liAllNoRead = null; //未讀取的資料集合
//出版者 (觀察者)
subject subjectObj = new subject();
subjectObj.userID = "0137";
//訂閱者(被觀察者)
testBugObserver bugObserverObj = new testBugObserver();
releaseBugObserver applyObj = new releaseBugObserver();
subjectObj.attach(bugObserverObj);
subjectObj.attach(applyObj);
_liAllNoRead =
subjectObj.listAllNoRead(); //取回被觀察者們傳回的未讀取的資料
new Thread(() =>
{
foreach (viewData noRead in _liAllNoRead)
{
notifyIcon1.BalloonTipIcon = ToolTipIcon.Info;
notifyIcon1.BalloonTipText = noRead.type;
notifyIcon1.BalloonTipTitle = noRead.title;
notifyIcon1.ShowBalloonTip(5000);
Thread.Sleep(6000);
}
}).Start();
}
|
上圖的Windows
Gridview資料分別由各自的被觀察者releaseBugObserver、testBugObserver 自已的findNoRead 找出來的資料
在正式版的公告-->新增bug --> 右下角跳出提醒視窗
在測試版的公告-->新增bug --> 右下角跳出提醒視窗
這樣以後不論有多少網站,需要有提醒功能,只要加上新的observer的物件,就不用再修改任何程式,一樣就有提醒功能,如果觀念誤導大家時,請各位前輩多多指導,學習的道路上本來就是永無止盡的,期望大家也能更上一層樓。
沒有留言:
張貼留言