




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第深入理解Java中觀察者模式與委托的對比目錄代碼背景觀察者模式介紹實現(xiàn)觀察者(學(xué)生)通知者(老師)Main方法觀察者通知者事件事件處理委托介紹總結(jié)
代碼背景
一個班級,有兩類學(xué)生,A類:不學(xué)習(xí),玩,但是玩的東西不一樣,有的是做游戲,有的是看電視
B類:放哨的學(xué)生,專門看老師的動向,如果老師進(jìn)班了就立即通知大家。
如此就形成了一個需求,放哨的學(xué)生要通知所有玩的學(xué)生:老師來了,而不同的學(xué)生有不同的反應(yīng),有的馬上把電視關(guān)閉,有的停止玩游戲。
觀察者模式
介紹
觀察者模式:定義了一種一對多的依賴關(guān)系,讓多個觀察者對象同時監(jiān)聽某一個主題對象。
這個主題對象在狀態(tài)發(fā)生變化時,會通知所有的觀察者對象,使他們能夠自動更新自己。
主要解決:一個對象狀態(tài)改變給其他對象通知的問題,而且要考慮到易用和低耦合,保證高度的協(xié)作。
何時使用:一個對象(目標(biāo)對象)的狀態(tài)發(fā)生改變,所有的依賴對象(觀察者對象)都將得到通知,進(jìn)行廣播通知。
如何解決:使用面向?qū)ο蠹夹g(shù),可以將這種依賴關(guān)系弱化。
關(guān)鍵代碼:在抽象類里有一個ArrayList存放觀察者們。
實現(xiàn)
觀察者(學(xué)生)
/**
*抽象的觀察者
*@authorPromsing(張有博)
*@version1.0.0
*@since2025/5/10-15:32
publicinterfaceObserver{
publicabstractvoidupdateState();
*具體的觀察者
*@authorPromsing(張有博)
*@version1.0.0
*@since2025/5/10-15:39
publicclassConcreteObserverimplementsObserver{
//觀察者的姓名
privateStringname;
//觀察者的狀態(tài)
privateStringobserverState;
//明確具體的通知者
privateConcreteSubjectsubject;
//getset方法省略
publicConcreteObserver(Stringname,ConcreteSubjectsubject){
=name;
this.subject=subject;
@Override
publicvoidupdateState(){
observerState=subject.getSubjectState();
System.out.println(name+"在打游戲");
Stringstr=String.format("觀察者%s的:新狀態(tài)是%s",name,observerState);
System.out.println(str);
*具體的觀察者
*@authorPromsing(張有博)
*@version1.0.0
*@since2025/5/10-15:39
publicclassConcreteObserver2implementsObserver{
//觀察者的姓名
privateStringname;
//觀察者的狀態(tài)
privateStringobserverState;
//明確具體的通知者
privateConcreteSubjectsubject;
//getset方法省略
publicConcreteObserver2(Stringname,ConcreteSubjectsubject){
=name;
this.subject=subject;
@Override
publicvoidupdateState(){
observerState=subject.getSubjectState();
System.out.println(name+"在看電視");
Stringstr=String.format("觀察者%s:新狀態(tài)是%s",name,observerState);
System.out.println(str);
}
通知者(老師)
/**
*抽象的通知者
*@authorPromsing(張有博)
*@version1.0.0
*@since2025/5/10-15:30
publicabstractclassSubject{
//管理觀察者的集合
privateListObserverobservers=newArrayList();
//增加觀察者
publicvoidadd(Observerobserver){
observers.add(observer);
//減少觀察者
publicvoiddetach(Observerobserver){
observers.remove(observer);
*通知所有的觀察者
publicvoidnotifyMsg(){
for(Observerobserver:observers){
observer.updateState();
*具體的通知者
*@authorPromsing(張有博)
*@version1.0.0
*@since2025/5/10-15:38
publicclassConcreteSubjectextendsSubject{
//通知者的狀態(tài)
privateStringsubjectState;
//getset方法
publicStringgetSubjectState(){
returnsubjectState;
publicvoidsetSubjectState(StringsubjectState){
this.subjectState=subjectState;
}
Main方法
/**
*控制臺Main方法
*@authorPromsing(張有博)
*@version1.0.0
*@since2025/5/10-15:48
publicclassMainTest{
publicstaticvoidmain(String[]args){
//創(chuàng)建一個主題/通知者
ConcreteSubjectsubject=newConcreteSubject();
//new出觀察者(學(xué)生)
ConcreteObserverstudentZhang=newConcreteObserver("小張",subject);
ConcreteObserverstudentLiu=newConcreteObserver("小劉",subject);
ConcreteObserverstudentWang=newConcreteObserver("小王",subject);
//將觀察者添加到通知隊列里
subject.add(studentZhang);
subject.add(studentLiu);
subject.add(studentWang);
//通知者(老師)狀態(tài)修改,通知每個學(xué)生
subject.setSubjectState("老師回來了,我要好好學(xué)習(xí)");
subject.notifyMsg();
System.out.println("-----------");
}
委托介紹
委托可以看做是函數(shù)的抽象,是函數(shù)的類。委托的實例將代表一個具體的函數(shù)
一個委托可以搭載多個方法,所有的方法被依次喚起??梢允刮袑ο笏钶d的方法并不需要屬于同一類。
委托事件模型可以由三個組件定義:事件、事件源和事件偵聽器。
委托的實現(xiàn)簡單來講就是用反射來實現(xiàn)的。
實現(xiàn)
觀察者
/**
*監(jiān)聽器/觀察者玩游戲
*事件監(jiān)聽器
*@authorPromsing(張有博)
*@version1.0.0
*@since2025/5/8-11:17
publicclassPlayingGameListener{
publicPlayingGameListener(){
System.out.println("我正在玩游戲開始時間"+newDate());
publicvoidstopPlayingGame(Datedate){
System.out.println("老師來了,快回到座位上,結(jié)束時間"+date);
*監(jiān)聽器/觀察者看電視
*事件監(jiān)聽器
*@authorPromsing(張有博)
*@version1.0.0
*@since2025/5/8-11:17
publicclassWatchingTVListener{
publicWatchingTVListener(){
System.out.println("我正在看電視"+newDate());
publicvoidstopWatchingTV(Datedate){
System.out.println("老師來了,快關(guān)閉電視。結(jié)束時間"+date);
}
通知者
/**
*通知者的抽象類
*事件源
*@authorPromsing(張有博)
*@version1.0.0
*@since2025/5/8-11:15
publicabstractclassNotifier{
//每個通知者都有一個需要通知的隊列(通知:對象、方法、參數(shù))
privateEventHandlereventHandler=newEventHandler();
publicEventHandlergetEventHandler(){
returneventHandler;
publicvoidsetEventHandler(EventHandlereventHandler){
this.eventHandler=eventHandler;
//增加需要幫忙放哨的學(xué)生
publicabstractvoidaddListener(Objectobject,StringmethodName,Object...args);
//告訴所有要幫忙放哨的學(xué)生:老師來了
publicabstractvoidnotifyX();
*通知者的子類,放哨人
*事件源
*@authorPromsing(張有博)
*@version1.0.0
*@since2025/5/8-11:15
publicclassGoodNotifierextendsNotifier{
@Override
publicvoidaddListener(Objectobject,StringmethodName,Object...args){
System.out.println("有新的同學(xué)委托盡職盡責(zé)的放哨人!");
this.getEventHandler().addEvent(object,methodName,args);
@Override
publicvoidnotifyX(){
System.out.println("盡職盡責(zé)的放哨人告訴所有需要幫忙的同學(xué):老師來了");
try{
//優(yōu)化:異步通知
this.getEventHandler().notifyX();
}catch(Exceptione){
e.printStackTrace();
}
事件
/**
*抽象出的事件類,也可以稱為方法類
*事件
*@authorPromsing(張有博)
*@version1.0.0
*@since2025/5/8-11:03
publicclassEvent{
//要執(zhí)行方法的對象
privateObjectobject;
//要執(zhí)行的方法名稱
privateStringmethodName;
//要執(zhí)行方法的參數(shù)
privateObject[]params;
//要執(zhí)行方法的參數(shù)類型
privateClass[]paramTypes;
//若干settergetter
publicObjectgetObject(){
returnobject;
publicStringgetMethodName(){
returnmethodName;
publicvoidsetMethodName(StringmethodName){
this.methodName=methodName;
publicObject[]getParams(){
returnparams;
publicvoidsetParams(Object[]params){
this.params=params;
publicClass[]getParamTypes(){
returnparamTypes;
publicvoidsetParamTypes(Class[]paramTypes){
this.paramTypes=paramTypes;
publicEvent(){
publicEvent(Objectobject,StringmethodName,Object...args){
this.object=object;
this.methodName=methodName;
this.params=args;
contractParamTypes(this.params);
//根據(jù)參數(shù)數(shù)組生成參數(shù)類型數(shù)組
privatevoidcontractParamTypes(Object[]params){
this.paramTypes=newClass[params.length];
for(inti=0;iparams.length;i++){
this.paramTypes[i]=params[i].getClass();
//執(zhí)行該對象的該方法
publicvoidinvoke()throwsException{
//通過class,method,paramTypes確定執(zhí)行哪個類的哪個方法
Methodmethod=object.getClass().getMethod(this.getMethodName(),this.getParamTypes());
if(null==method){
return;
//方法執(zhí)行
method.invoke(this.getObject(),this.getParams());
}
事件處理
/**
*管理哪些事件需要執(zhí)行
*管理事件
*@authorPromsing(張有博)
*@version1.0.0
*@since2025/5/8-11:03
publicclassEventHandler{
//是用一個List
privateListEventobjects;
//添加某個對象要執(zhí)行的事件,及需要的參數(shù)
publicvoidaddEvent(Objectobject,StringmethodName,Object...args){
objects.add(newEvent(object,methodName,args));
publicEventHandler(){
objects=newArrayListEvent
//通知所有的對象執(zhí)行指定的事件
publicvoidnotifyX()throwsException{
for(Evente:objects){
e.invoke();
}
Main方法
/**
*啟動類
*@authorPromsing(張有博)
*@version1.0.0
*@since2025/5/8-11:19
publicclassEventMain{
publicstaticvoidmain(String[]args){
//創(chuàng)建一個盡職盡責(zé)的放哨者
NotifiergoodNotifier=newGoodNotifier();
//創(chuàng)建一個玩游戲的同學(xué),開始玩游戲
PlayingGameListenerplayingGameListener=newPlayingGameListener();
//創(chuàng)建一個看電視的同學(xué),開始看電視
WatchingTVListenerwatchingTVListener=newWatchingTVListener();
//玩游戲的同學(xué)告
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 合同協(xié)議入伙協(xié)議
- 廠房房屋建筑合同
- 營銷代理合作協(xié)議條款及細(xì)則
- 拆遷工程居間合同
- 犬只配種協(xié)議書
- 比賽培訓(xùn)協(xié)議書
- 運(yùn)動員訓(xùn)練協(xié)議合同
- 水源借用協(xié)議書
- 日語框架協(xié)議書
- 濱州港口協(xié)議書
- 【《長虹美菱基于EVA的業(yè)績評價的案例分析》9800字】
- 2024年03月安徽合肥市第二人民醫(yī)院招考聘用工作人員79人筆試近年2018-2023典型考題及考點(diǎn)剖析附答案帶詳解
- 【N600MW發(fā)電機(jī)組改供熱探析17000字(論文)】
- 【應(yīng)收賬款管理問題及完善策略:以S建工集團(tuán)公司為例9800字(論文)】
- 2024綠色工業(yè)園區(qū)評價通則
- DL-T5372-2017水電水利工程金屬結(jié)構(gòu)與機(jī)電設(shè)備安裝安全技術(shù)規(guī)程
- 人教版數(shù)學(xué)《認(rèn)識鐘表》公開課課件1
- Pep 新版小學(xué)英語六年級下冊一般過去時復(fù)習(xí)課教案
- 產(chǎn)科10個臨床路徑
- 古埃及圣書手冊古代語言文字研究
- 兒科入院安全宣教
評論
0/150
提交評論