




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、下載APP73 | 中介模式:什么時候用中介模式?什么時候用觀察者模式?2020-04-20 王爭設計模式之美進入課程講述:馮永吉時長 07:43 大小 7.08M今天,我們來學習 23 種經典設計模式中的最后一個,中介模式。跟前面剛剛講過的命令模式、解釋器模式類似,中介模式也屬于不怎么常用的模式,應用場景比較特殊、有限,但是,跟它倆不同的是,中介模式理解起來并不難,代碼實現也非常簡單,學習難度要小很多。如果你對中介模式有所了解,你可能會知道,中介模式跟之前講過的觀察者模式有點相似, 所以,今天我們還會詳細討論下這兩種模式的區(qū)別。話不多說,讓我們正式開始今天的學習吧!中介模式的原理和實現中介模
2、式的英文翻譯是 Mediator Design Pattern。在 GoF 中的設計模式一書中,它是這樣定義的:Mediator pattern defines a separate (mediator) object that encapsulates the interaction between a set of objects and the objects delegate their interaction to a mediator object instead of interacting with each other directly.翻譯成中文就是:中介模式定義了一個單獨
3、的(中介)對象,來封裝一組對象之間的交互。將這組對象之間的交互委派給與中介對象交互,來避免對象之間的直接交互。還記得我們在第 30 節(jié)課中講的“如何給代碼解耦”嗎?其中一個方法就是引入中間層。實際上,中介模式的設計思想跟中間層很像,通過引入中介這個中間層,將一組對象之間的交互關系(或者說依賴關系)從多對多(網狀關系)轉換為一對多(星狀關系)。原來一個對象要跟 n 個對象交互,現在只需要跟一個中介對象交互,從而最小化對象之間的交互關系, 降低了代碼的復雜度,提高了代碼的可讀性和可維護性。這里我畫了一張對象交互關系的對比圖。其中,右邊的交互圖是利用中介模式對左邊交互關系優(yōu)化之后的結果,從圖中我們可
4、以很直觀地看出,右邊的交互關系更加清晰、簡潔。提到中介模式,有一個比較經典的例子不得不說,那就是航空管制。為了讓飛機在飛行的時候互不干擾,每架飛機都需要知道其他飛機每時每刻的位置,這就需 要時刻跟其他飛機通信。飛機通信形成的通信網絡就會無比復雜。這個時候,我們通過引入“塔臺”這樣一個中介,讓每架飛機只跟塔臺來通信,發(fā)送自己的位置給塔臺,由塔臺來 負責每架飛機的航線調度。這樣就大大簡化了通信網絡。剛剛舉的是生活中的例子,我們再舉一個跟編程開發(fā)相關的例子。這個例子與 UI 控件有關, 算是中介模式比較經典的應用,很多書籍在講到中介模式的時候,都會拿它來舉例。假設我們有一個比較復雜的對話框,對話框中
5、有很多控件,比如按鈕、文本框、下拉框等。當我們對某個控件進行操作的時候,其他控件會做出相應的反應,比如,我們在下拉框中選擇“注冊”,注冊相關的控件就會顯示在對話框中。如果我們在下拉框中選擇“登陸”,登陸相關的控件就會顯示在對話框中。復制代碼1 public class UIControl 1011121314151617181920212223242526public static void main(String args) Button loginButton = (Button)findViewById(LOGIN_BTN_ID); Button regButton = (Button)
6、findViewById(REG_BTN_ID);Input usernameInput = (Input)findViewById(USERNAME_INPUT_ID); Input passwordInput = (Input)findViewById(PASSWORD_INPUT_ID);Input repeatedPswdInput = (Input)findViewById(REPEATED_PASSWORD_INPUT_ID); Text hintText = (Text)findViewById(HINT_TEXT_ID);Selection selection = (Selec
7、tion)findViewById(SELECTION_ID);loginButton.setOnClickListener(new OnClickListener() Overridepublic void onClick(View v) String username = usernameInput.text(); String password = passwordInput.text();/校驗數據./做業(yè)務處理.按照通常我們習慣的 UI 界面的開發(fā)方式,我們將剛剛的需求用代碼實現出來,就是下面這個樣子。在這種實現方式中,控件和控件之間互相操作、互相依賴。2privatestaticf
8、inalStringLOGIN_BTN_ID = login_btn;3privatestaticfinalStringREG_BTN_ID = reg_btn;4privatestaticfinalStringUSERNAME_INPUT_ID = username_input;5privatestaticfinalStringPASSWORD_INPUT_ID = pswd_input;6privatestaticfinalStringREPEATED_PASSWORD_INPUT_ID = repeated_pswd_inpu7privatestaticfinalStringHINT_T
9、EXT_ID = hint_text;8privatestaticfinalStringSELECTION_ID = selection;927);2829regButton.setOnClickListener(new OnClickListener() 30Override31public void onClick(View v) 32/獲取usernameInput、passwordInput、repeatedPswdInput數據.33/校驗數據.34/做業(yè)務處理.3536);3738/.省略selection下拉選擇框相關代碼.39 40 我們再按照中介模式,將上面的代碼重新實現一下
10、。在新的代碼實現中,各個控件只跟中介對象交互,中介對象負責所有業(yè)務邏輯的處理。復制代碼1 public interface Mediator 2 void handleEvent(Component component, String event);3 45 public class LandingPageDialog implements Mediator 6 private Button loginButton;7 private Button regButton;8 private Selection selection;9 private Input usernameInput;10
11、private Input passwordInput;11 private Input repeatedPswdInput;12 private Text hintText;1314 Override15 public void handleEvent(Component component, String event) 16 if (component.equals(loginButton) 17 String username = usernameInput.text();18 String password = passwordInput.text();19/校驗數據.20 /做業(yè)務處
12、理.21 else if (component.equals(regButton) 22 /獲取usernameInput、passwordInput、repeatedPswdInput數據.23/校驗數據.24 /做業(yè)務處理.25 else if (component.equals(selection) 26 String selectedItem = selection.select();27 if (selectedItem.equals(login) 28 usernameInput.show();29 passwordInput.show();30repeatedPswdInput.
13、hide();31hintText.hide();32/.省略其他代碼33 else if (selectedItem.equals(register) 34/.353637383940public class UIControl 41privatestaticfinalStringLOGIN_BTN_ID = login_btn;42privatestaticfinalStringREG_BTN_ID = reg_btn;43privatestaticfinalStringUSERNAME_INPUT_ID = username_input;44privatestaticfinalStrin
14、gPASSWORD_INPUT_ID = pswd_input;45privatestaticfinalStringREPEATED_PASSWORD_INPUT_ID = repeated_pswd_inpu46privatestaticfinalStringHINT_TEXT_ID = hint_text;47privatestaticfinalStringSELECTION_ID = selection;4849 public static void main(String args) 50 Button loginButton = (Button)findViewById(LOGIN_
15、BTN_ID);51 Button regButton = (Button)findViewById(REG_BTN_ID);52 Input usernameInput = (Input)findViewById(USERNAME_INPUT_ID);53 Input passwordInput = (Input)findViewById(PASSWORD_INPUT_ID);54 Input repeatedPswdInput = (Input)findViewById(REPEATED_PASSWORD_INPUT_ID);55 Text hintText = (Text)findVie
16、wById(HINT_TEXT_ID);56 Selection selection = (Selection)findViewById(SELECTION_ID);5758 Mediator dialog = new LandingPageDialog();59 dialog.setLoginButton(loginButton);60 dialog.setRegButton(regButton);61 dialog.setUsernameInput(usernameInput);62 dialog.setPasswordInput(passwordInput);63 dialog.setR
17、epeatedPswdInput(repeatedPswdInput);64 dialog.setHintText(hintText);65 dialog.setSelection(selection);6667 loginButton.setOnClickListener(newOnClickListener() 68 Override69 public void onClick(View v) 70 dialog.handleEvent(loginButton, click);7172);7374 regButton.setOnClickListener(new OnClickListen
18、er() 75 Override76 public void onClick(View v) 77 dialog.handleEvent(regButton, click);7879);8081/.8283從代碼中我們可以看出,原本業(yè)務邏輯會分散在各個控件中,現在都集中到了中介類中。實際上,這樣做既有好處,也有壞處。好處是簡化了控件之間的交互,壞處是中介類有可能會變成大而復雜的“上帝類”(God Class)。所以,在使用中介模式的時候,我們要根據實際的情況,平衡對象之間交互的復雜度和中介類本身的復雜度。中介模式 VS 觀察者模式前面講觀察者模式的時候,我們講到,觀察者模式有多種實現方式。雖然
19、經典的實現方式沒法徹底解耦觀察者和被觀察者,觀察者需要注冊到被觀察者中,被觀察者狀態(tài)更新需要調用觀察者的 update() 方法。但是,在跨進程的實現方式中,我們可以利用消息隊列實現徹底解耦,觀察者和被觀察者都只需要跟消息隊列交互,觀察者完全不知道被觀察者的存在,被觀察者也完全不知道觀察者的存在。我們前面提到,中介模式也是為了解耦對象之間的交互,所有的參與者都只與中介進行交互。而觀察者模式中的消息隊列,就有點類似中介模式中的“中介”,觀察者模式的中觀察 者和被觀察者,就有點類似中介模式中的“參與者”。那問題來了:中介模式和觀察者模式 的區(qū)別在哪里呢?什么時候選擇使用中介模式?什么時候選擇使用觀
20、察者模式呢?在觀察者模式中,盡管一個參與者既可以是觀察者,同時也可以是被觀察者,但是,大部分情況下,交互關系往往都是單向的,一個參與者要么是觀察者,要么是被觀察者,不會兼具兩種身份。也就是說,在觀察者模式的應用場景中,參與者之間的交互關系比較有條理。而中介模式正好相反。只有當參與者之間的交互關系錯綜復雜,維護成本很高的時候,我們才考慮使用中介模式。畢竟,中介模式的應用會帶來一定的副作用,前面也講到,它有可能會產生大而復雜的上帝類。除此之外,如果一個參與者狀態(tài)的改變,其他參與者執(zhí)行的操作有一定先后順序的要求,這個時候,中介模式就可以利用中介類,通過先后調用不同參與者的方法,來實現順序的控制,而觀
21、察者模式是無法實現這樣的順序要求的。重點回顧好了,今天的內容到此就講完了。我們一塊來總結回顧一下,你需要重點掌握的內容。中介模式的設計思想跟中間層很像,通過引入中介這個中間層,將一組對象之間的交互關系(或者依賴關系)從多對多(網狀關系)轉換為一對多(星狀關系)。原來一個對象要跟 n 個對象交互,現在只需要跟一個中介對象交互,從而最小化對象之間的交互關系,降低了代碼的復雜度,提高了代碼的可讀性和可維護性。觀察者模式和中介模式都是為了實現參與者之間的解耦,簡化交互關系。兩者的不同在于應用場景上。在觀察者模式的應用場景中,參與者之間的交互比較有條理,一般都是單向的, 一個參與者只有一個身份,要么是觀
22、察者,要么是被觀察者。而在中介模式的應用場景中, 參與者之間的交互關系錯綜復雜,既可以是消息的發(fā)送者、也可以同時是消息的接收者。課堂討論s 框在講觀察者模式的時候,我們有講到 EventBu架。當時我們認為它是觀察者模式的實現框架。EventBus作為一個 處理的中心,的派送、訂閱都通過這個中心來完成,那是不是更像中介模式的實現框架呢?歡迎留言和我分享你的想法。如果有收獲,也歡迎你把這篇文章分享給你的朋友。 版權歸極客邦科技所有,未經許可不得傳播售賣。 頁面已增加防盜追蹤,如有侵權極客邦將依法追究其法律責任。上一篇72 | 解釋器模式:如何設計實現一個自定義接口告警規(guī)則功能?下一篇74 | 總
23、結回顧23種經典設計模式的原理、背后的思想、應用場景等寫留言精選留言 (16)大頭2020-04-20想到了現在流行的微服務,注冊中心可以理解為廣義的中介模式,防止各個服務間錯綜復雜的調用13小晏子2020-04-20eventbus更屬于觀察者模式,首先eventbus中不處理業(yè)務邏輯,只提供了對象與對象之間交互的管道;而中介模式為了解決多個對象之間交互的問題,將多個對象的行為封裝到一起(中介),然后任意對象和這個中介交互,中介中包含了具體業(yè)務邏輯。其次從其實現的思路上,EventBus 和觀察者都需要定義 Observer,并且通過 register() 函數注冊 Obs erver,也都
24、需要通過調用某個函數(比如,EventBus 中的 post() 函數)來給 Observe展開 19李小四2020-04-20設計模式_73:# 作業(yè):個人認為還是觀察者模式,當然,引入消息隊列的觀察者模式可以理解為中介模式的一種,它的業(yè)務調用更有規(guī)律,它不要求被調用者的順序。展開3小文同學2020-04-20eventbus 是不帶業(yè)務處理的,而且bus不會隨著業(yè)務復雜而改變,所以屬于觀察者模式1test2020-04-20eventbus解決的是消息的發(fā)布訂閱等,跟具體的業(yè)務沒關系,所以是觀察者模式1eason20172020-04-20從定義上看,中介模式是解決一組對象之間的交互,而E
25、venybus并不是解決這塊的,解決的是所有觀察者和被觀察者之間的交互方式。所以,確切的說,它并不算中介模式。不知回答是否正確,請指點,謝謝11黃林晴2020-04-20打卡在實際的開發(fā)中 UI 控件變化那種感覺不太適合中介模式因為要把所有的控件view 都傳到中介類中才可以獲取到輸入的內容 感覺比較奇怪,就像只是把某個方法單獨提取到一個類中一樣展開 1 1iLeGeND2020-04-20感覺23中設計模式之間本身就有某種耦合 好多不易區(qū)分展開21Jxin2020-04-221. 總線屬于觀察者模式。因為訂閱的操作雖然是在中心執(zhí)行,但卻是由觀察者發(fā)起 的,且后續(xù)消息分派都遵循當前的訂閱規(guī)則。也就是說觀察者模式的中心,只干活,不決定干活的方式,分派規(guī)則與運行時的數據流無關。而中介模式不一樣,中介模式消息派送是由每個參與者的每次調用時決定的,中心需要維護一套協(xié)調所有參與者相互通信的規(guī)則,并根據數據流協(xié)調多個參與者間的交互。也就是說,中介者模式的中心,要干活,展開Ge
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 彈弓指 的護理及運動
- 2025至2030巴基斯坦基礎建設行業(yè)產業(yè)運行態(tài)勢及投資規(guī)劃深度研究報告
- 商業(yè)綜合體的安全管理及風險控制策略研究報告
- 中藥與腸道微生態(tài)的關聯(lián)研究
- 2025至2030維生素口嚼片行業(yè)項目調研及市場前景預測評估報告
- 2025至2030中國自由飛行服行業(yè)市場占有率及投資前景評估規(guī)劃報告
- 2025至2030中國自動裝配機行業(yè)產業(yè)運行態(tài)勢及投資規(guī)劃深度研究報告
- 2025至2030中國自主無人機無線充電和基礎設施行業(yè)市場占有率及投資前景評估規(guī)劃報告
- 2025至2030中國腕式潛水電腦行業(yè)發(fā)展趨勢分析與未來投資戰(zhàn)略咨詢研究報告
- 2025至2030中國能源行業(yè)市場發(fā)展分析及投資前景與投資策略報告
- 自由搏擊培訓方案
- 防火門安裝工程操作管理規(guī)程
- (2025)全國交管12123學法減分考試題庫附答案
- 虛擬現實行業(yè)標準-深度研究
- T-ZHCA 025-2023 化妝品抗氧化人體測試方法
- 包皮環(huán)切術的健康宣教
- 班級優(yōu)化大師使用培訓
- 醫(yī)院后勤保障與傳染病防控
- 北師版五年級下冊數學30道說理題
- 質量管理的五年規(guī)劃
- 《商業(yè)攝影》課件
評論
0/150
提交評論