基礎才是重中之重~B/S系(xi)統(tong)中的(de)事件訂閱
我之前寫一篇關于事件訂閱的文章(事件的好處~實現對修改的封閉,對擴展的開放!~續),但它主要是訂(ding)閱靜態事(shi)件,而(er)今天(tian)主要講(jiang)的(de)是實例(li)事(shi)件,即,當一個(ge)事(shi)件發布者被實例(li)化后,去(qu)(qu)訂(ding)閱它里面(mian)的(de)事(shi)件,然后當這個(ge)事(shi)件發布者去(qu)(qu)觸發該(gai)事(shi)件時,自己執行你訂(ding)閱的(de)內容,這沒(mei)什么可說的(de),一切都(dou)很正(zheng)常。
但在B/s系統中,常(chang)常(chang)都有這樣一種需(xu)(xu)求,即:Order類(lei)中有方(fang)(fang)法(fa)(fa)GeneratorOrder,即生成(cheng)訂單的方(fang)(fang)法(fa)(fa),這個方(fang)(fang)法(fa)(fa)會被UI層的很(hen)多方(fang)(fang)法(fa)(fa)調用,以(yi)實(shi)現(xian)對不同(tong)業務產(chan)品(pin)的購(gou)買,如(ru):購(gou)買家電產(chan)品(pin),購(gou)買成(cheng)功后應該去和家電有關(guan)的成(cheng)功頁;而購(gou)買日(ri)常(chang)用品(pin),成(cheng)功后應該去與日(ri)常(chang)用戶相關(guan)的頁面;以(yi)后還會有其它業務產(chan)品(pin)的成(cheng)功頁,需(xu)(xu)要我們去實(shi)現(xian)。
作法1:用static event,靜態(tai)事件,但有一(yi)個問題,由于它是對類而言的事件,所(suo)以(yi)A用戶訂閱的事件,在B用戶通過瀏(liu)覽器(qi)查看時,也會訂閱這個事件,所(suo)以(yi),靜態(tai)事件不能(neng)滿足我們的要求(一(yi)般用靜態(tai)事件做全局性的工作)
作(zuo)法2:直接把所有產品所對應(ying)的(de)成(cheng)功(gong)頁寫(xie)在Generatororder方(fang)法里,通(tong)過switch去分(fen)別處理;這(zhe)種作(zuo)法可以解(jie)決這(zhe)個問題(ti),但這(zhe)樣的(de)程序(xu)(xu)沒(mei)有任何的(de)可擴展性而言,也不是(shi)真正面(mian)向對象的(de)程序(xu)(xu)。
作法3:使(shi)用普(pu)通事(shi)件(jian),在產品A訂閱(yue)完成(cheng)事(shi)件(jian)后,將(jiang)事(shi)件(jian)發布者以參數的形式,傳遞給generatororder方法,這就一種最標準(zhun),更可靠的作法。
代碼如下:
1 /// <summary> 2 /// 事(shi)件發(fa)布者 3 /// </summary> 4 public partial class ReturnMsgClass 5 { 6 partial void OnLoad(); 7 public ReturnMsgClass() 8 { 9 OnLoad(); 10 } 11 12 #region Events 13 /// <summary> 14 /// 返回(hui)消息事(shi)件[實例事(shi)件] 15 /// </summary> 16 public event Func<string> ReturnMsg; 17 #endregion 18 19 #region OnEvents Methods 20 /// <summary> 21 /// 觸發ReturnMsg事件 22 /// </summary> 23 public string OnReturnMsg() 24 { 25 if ((this.ReturnMsg != null)) 26 { 27 return this.ReturnMsg(); 28 } 29 else 30 return "沒有訂(ding)閱事件"; 31 } 32 #endregion 33 }
下面(mian)是事(shi)(shi)件(jian)的(de)(de)訂(ding)閱者(zhe),它(ta)應該傳入的(de)(de)事(shi)(shi)件(jian)發(fa)布者(zhe)對象,去訂(ding)閱相(xiang)應的(de)(de)事(shi)(shi)件(jian)
1 /// <summary> 2 /// 事件訂閱者 3 /// </summary> 4 public class Subscriber 5 { 6 public Subscriber(ReturnMsgClass returnMsgClass, string url) 7 { 8 returnMsgClass.ReturnMsg += delegate() { return url; }; 9 } 10 }
而對(dui)于(yu)A類(lei)產品在購買成功后,然后執(zhi)行一些邏(luo)輯
1 public partial class HomeController 2 { 3 public ActionResult Test() 4 { 5 ReturnMsgClass rm = new ReturnMsgClass(); 6 Subscriber sub = new Subscriber(rm, "//www.sina.com");//如果訂閱成功,就將這個地(di)址(zhi)返(fan)回 7 return View("Index", rm); 8 } 9 }
而在購買成功(gong)頁(ye),將會有這(zhe)樣的重定向的邏(luo)輯
1 @{ 2 Response.Redirect((Model as TEstMv3.Controllers.ReturnMsgClass ?? new TEstMv3.Controllers.ReturnMsgClass()).OnReturnMsg()); 3 }
最后(hou),實現的(de)效果就是,當用戶訪問test頁面時,事件后(hou)訂閱,然后(hou)自動(dong)跳轉到指定的(de)頁面。