java委托事件与观察者模式_多播委托与观察者模式联合使用,以及委托与事件的区别...
首先我們先看一下多播委托:
使用委托時,首先我們聲明委托,委托語法一共有四種類型,分別時有參,無參,以及有無參數(shù)返回值。
1 public class DelegateShow //: System.MulticastDelegate,多播委托
2 {3 public delegate void NoReturnNoPara();//1 聲明委托 一個沒有方法體的方法,加上delegate關(guān)鍵字
4 public delegate void NoReturnWithPara(Student student, int size, stringremark);5 public delegate stringWithReturnNoPara();6 public delegate Student WithReturnWithPara(string name, int id);
View Code
接下來,我們寫一個無參的方法:
1 private voidShowNothing()2 {3 Console.WriteLine("This is ShowNothing");4 }
View Code
哦,對了,還要在頂類里面定義下方法,方便后面調(diào)用:
public classOtherClass
{public voidShowNothing()
{
Console.WriteLine("This is ShowNothing");
}public static voidShowNothingStatic()
{
Console.WriteLine("This is ShowNothing");
}
}
View Code
好,接下來,我們開始委托實例化,調(diào)用委托:
1 OtherClass otherClass = newOtherClass();2
3 //多播委托就是一個方法列表 +=在列表尾巴上加方法,4 //-=就是從尾巴開始匹配,只移除第一個完全吻合方法,如果沒有吻合,不報錯
5 NoReturnNoPara method = new NoReturnNoPara(ShowNothing);//放入ShowNothing
6 method += otherClass.ShowNothing;//再放入2
7 method += OtherClass.ShowNothingStatic;//再放入3
8 method += OtherClass.ShowNothingStatic;//再放入3
9 method += OtherClass.ShowNothingStatic;//再放入3
10 method += () => Console.WriteLine("123456");11 method.Invoke();12
13 //method.BeginInvoke(null, null);//多播委托不能直接異步
14 foreach (NoReturnNoPara item inmethod.GetInvocationList())15 {16 item.BeginInvoke(null, null);17 }18
19 Console.WriteLine("***********************************************");20 method -=ShowNothing;21 method -= otherClass.ShowNothing;//減少2
22 method -= OtherClass.ShowNothingStatic;//減少3
23 method -= () => Console.WriteLine("123456");24 method.Invoke();25 Console.WriteLine("***********************************************");
View Code
說一下:個人覺得多播委托,就是以事件為參數(shù)放到多播委托這個列表里面,放到列表的語法就是+=,從列表移除的方法就是-=,但是多播委托是不支持異步的,所以這里我們就要
調(diào)用一個封裝的參數(shù)method.GetInvocationList(),配合BeginInvoke()就可以實現(xiàn)多播委托異步。
還有一個知識點就是,多播委托為變量配合lambda使用時,多個返回值只能返回最后一個值:
1 WithReturnNoPara method = () =>DateTime.Now.ToString();2 Console.WriteLine(method.Invoke());3
4 method += () => "1";5 method += () => "2";6 method += () => "3";7 method += () => "4";8 method += () => "5";9 Console.WriteLine(method.Invoke());//待返回值的多播委托,只能獲得最后一個方法的返回值
View Code
好了,接下來我們說一下觀察者模式,這里我拷貝了一下觀察者模式具體是一個什么樣的業(yè)務(wù)場景。
觀察者模式(Observer)完美的將觀察者和被觀察的對象分離開。舉個例子,用戶界面可以作為一個觀察者,業(yè)務(wù)數(shù)據(jù)是被觀察者,用戶界面觀察業(yè)務(wù)數(shù)據(jù)的變化,發(fā)現(xiàn)數(shù)據(jù)變化后,就顯示在界面上。面向?qū)ο笤O(shè)計的一個原則是:系統(tǒng)中的每個類將重點放在某一個功能上,而不是其他方面。一個對象只做一件事情,并且將他做好。觀察者模式在模塊之間劃定了清晰的界限,提高了應(yīng)用程序的可維護性和重用性。
觀察者設(shè)計模式定義了對象間的一種一對多的依賴關(guān)系,以便一個對象的狀態(tài)發(fā)生變化時,所有依賴于它的對象都得到通知并自動刷新。
額,這個是百度出來的意義,具體我舉一個例子:例子就是貓、狗、小孩、老鼠,由于貓的一個動作發(fā)生的一起連鎖反應(yīng)。
如果單純實現(xiàn)功能,方法有很多,或許我們可以這樣寫:
1 public classCat2 {3 public voidMiao()4 {5 Console.WriteLine("貓 miao了一聲。。。");6
7
8 Dog.Wang();9 Mouse.Run();10 People.Awake();11 Stealer.Hide();12 Baby.Cry();13 }
View Code
這樣確實可以實現(xiàn)功能,但是這樣帶來了很多不好的地方,如果以后我們再增加觀察者或者修改觀察者的動作,都會破壞當(dāng)前這個方法,也違背了單一職責(zé),耦合比較高,難維護等缺點,這時,就用到了我們委托來解偶啦。
具體來看代碼:
1 public delegate void CatMiaoDelegate(); //聲明委托;
2 publicCatMiaoDelegate CatMiaoDelegateHandler;3 public voidMiaoDelegate()4 {5 Console.WriteLine("貓 MiaoDelegate了一聲。。。");6 if (CatMiaoDelegateHandler != null)7 {8 CatMiaoDelegateHandler.Invoke(); //實現(xiàn)委托;
9 }10
11 }12
View Code
Cat cat = newCat();
cat.Miao();
cat.CatMiaoDelegateHandler+=Mouse.Run;
cat.CatMiaoDelegateHandler.Invoke();
cat.CatMiaoDelegateHandler= null;
cat.CatMiaoDelegateHandler+=Dog.Wang;
cat.CatMiaoDelegateHandler+=People.Awake;
cat.CatMiaoDelegateHandler+=Stealer.Hide;
cat.CatMiaoDelegateHandler+=Baby.Cry;
cat.CatMiaoDelegateHandler+=Brother.Turn;
cat.MiaoDelegate();//多播委托調(diào)用實現(xiàn)其他類方法;
View Code
這樣我們就把前面那個高耦合的方法中,得到了解耦的目的,并且在維護和增加其他觀察者時不用再次破壞方法,符合對擴展開放 ?對修改封閉的原則,這樣是極好的。
接下來再說一下委托和事件的區(qū)別把:
1、事件是委托的實例,加了一個event的關(guān)鍵字
2、委托是一種類型 事件是委托的實例
3、加event關(guān)鍵字后,控制了權(quán)限,不讓外部調(diào)用或者直接賦值
好了,上面?zhèn)€人總結(jié)對多播委托與觀察者綜合使用,以及委托與事件之間的區(qū)別。可能還有不對的地方,希望大牛多多指導(dǎo)。
總結(jié)
以上是生活随笔為你收集整理的java委托事件与观察者模式_多播委托与观察者模式联合使用,以及委托与事件的区别...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 强大的uml java_IDEA 还是强
- 下一篇: java扑克牌抽牌_[java,2018