Android设计模式之——中介者模式
一、介紹
中介者模式(Mediator Pattern)也稱(chēng)為調(diào)解者模式或調(diào)停者模式,Mediator本身就有調(diào)停者和調(diào)解者的意思。
在日常生活中調(diào)停者或調(diào)解者這個(gè)角色我們見(jiàn)得比較多的是“和事老”,也就是說(shuō)調(diào)解兩個(gè)有爭(zhēng)端的人的角色,舉個(gè)不恰當(dāng)?shù)睦?#xff0c;比如爸媽吵架,孩子或者雙方父母則會(huì)出面勸架或阻止?fàn)幊?#xff0c;這里孩子或雙方父母則是充當(dāng)?shù)氖钦{(diào)解者的模式。
而對(duì)于中介呢?大家平時(shí)聽(tīng)得最多的莫過(guò)于房產(chǎn)中介了,在房地產(chǎn)飛速發(fā)展的今天,各種房產(chǎn)中介公司如雨后春筍般冒出來(lái),房產(chǎn)中介承擔(dān)的責(zé)任很簡(jiǎn)單,就是在買(mǎi)房者與賣(mài)房者之間建立一座橋梁溝通兩者,比如小民現(xiàn)在手里有套房子需要出售,于是他找房產(chǎn)中介并告訴房產(chǎn)中介房子的期望售價(jià)和房子的相關(guān)信息,然后房產(chǎn)中介則將這些信息收集匯總有時(shí)還會(huì)美化一番,然后把廣告掛在櫥窗里等待買(mǎi)房者,如果有人有意向購(gòu)買(mǎi)這套房子,比如這里以小輝為例,房產(chǎn)中介就會(huì)告訴小輝關(guān)于這套房產(chǎn)的相關(guān)信息,如房齡、售價(jià)等,有時(shí)還會(huì)帶小輝去房子里實(shí)際參觀一番,最終小輝將自己的意愿告訴房產(chǎn)中介,再由房產(chǎn)中介去與小民進(jìn)行溝通。也就是說(shuō)在整個(gè)房產(chǎn)協(xié)商的過(guò)程中,小民和小輝買(mǎi)賣(mài)雙方是很少直接接觸的,大多數(shù)情況下都是通過(guò)房產(chǎn)中介來(lái)傳達(dá)信息,可能只有在最終進(jìn)行房產(chǎn)交接時(shí)小民和小輝才會(huì)正式見(jiàn)面。
這就是我們現(xiàn)實(shí)生活中常見(jiàn)的調(diào)解者與中介者,但是,這里我們要說(shuō)的中介者模式比起上述的兩個(gè)例子來(lái)要復(fù)雜的多,上面我們所述的例子中,中介者或調(diào)解者所要協(xié)調(diào)的也就兩類(lèi)對(duì)象,而我們的中介者模式中需要協(xié)調(diào)的是多類(lèi)對(duì)象。
這里還是舉一個(gè)小例子來(lái)說(shuō)明,本書(shū)的閱讀者大多都是IT從業(yè)者,說(shuō)得更準(zhǔn)確些都是做APP的,一般來(lái)說(shuō),一個(gè)做APP的公司可以分為幾大模塊:運(yùn)維、產(chǎn)品、開(kāi)發(fā)、設(shè)計(jì)還有測(cè)試,每當(dāng)一個(gè)新APP開(kāi)始制作或者發(fā)布新版本需要制作之前,公司會(huì)開(kāi)一個(gè)研討會(huì),運(yùn)維負(fù)責(zé)市場(chǎng)了解用戶使用傾向,研發(fā)的會(huì)說(shuō)用戶反映界面不好看要求修改界面……這樣大家你一句我一句的討論一半天也沒(méi)有啥實(shí)質(zhì)性結(jié)果,主要原因在于大家都站在自己的立場(chǎng)考慮問(wèn)題,這樣的團(tuán)隊(duì)研討會(huì)即使再開(kāi)下去也沒(méi)什么意義,這時(shí)候如果有一個(gè)人不屬于運(yùn)維、產(chǎn)品、開(kāi)發(fā)、設(shè)計(jì)任一方的人站出來(lái)說(shuō),大家把各自的意見(jiàn)都跟我說(shuō),由我來(lái)權(quán)衡并作出最終的決定,不管決定如何你們都要照做。因?yàn)檫@個(gè)人不代表任何一方,于是大家都全票表示肯定,這么一來(lái)一個(gè)方案很快就定下來(lái),而這個(gè)作出最終決定的人我們就稱(chēng)之為中介者,這里的中介者與我們的中介者模式一樣面對(duì)的是多類(lèi)對(duì)象,這里其實(shí)大家可以看到中介者模式的一些特性,每一個(gè)中介者都會(huì)知道所有的同事,比如上面我們所說(shuō)的運(yùn)維、產(chǎn)品、開(kāi)發(fā)、設(shè)計(jì)還有測(cè)試,但是這些同事呢可以互不相識(shí),而中介者不屬于同事的任何一方,也不偏袒任何一方,這么一說(shuō)相信大家對(duì)中介者模式會(huì)有一個(gè)非常清晰的了解。
二、定義
中介者模式包裝了一系列對(duì)象互相作用的方式,使得這些對(duì)象不必相互明顯作用。從而使它們可以松散偶合。當(dāng)某些對(duì)象之間的作用發(fā)生改變時(shí),不會(huì)立即影響其他的一些對(duì)象之間的作用。保證這些作用可以彼此獨(dú)立的變化。中介者模式將多對(duì)多的相互作用轉(zhuǎn)化為一對(duì)多的相互作用。中介者模式將對(duì)象的行為和協(xié)作抽象化,把對(duì)象在小尺度的行為上與其他對(duì)象的相互作用分開(kāi)處理。
三、使用場(chǎng)景
當(dāng)對(duì)象之間的交互操作很多且每個(gè)對(duì)象的行為操作都依賴彼此時(shí),為防止在修改一個(gè)對(duì)象的行為時(shí),同時(shí)涉及修改很多其他對(duì)象的行為,可采用中介者模式,來(lái)解決緊耦合問(wèn)題。該模式將對(duì)象之間的多對(duì)多關(guān)系變成一對(duì)多關(guān)系,中介者對(duì)象將系統(tǒng)從網(wǎng)狀結(jié)構(gòu)變成以調(diào)停者為中心的星形結(jié)構(gòu),達(dá)到降低系統(tǒng)的復(fù)雜性,提高可擴(kuò)展性的作用。
四、中介者模式的UML類(lèi)圖
UML類(lèi)圖:
角色介紹:
Mediator:抽象的中介者角色,定義了同事對(duì)象到中介者的接口。
ConcreteMediator:具體的中介者角色,從具體的同事對(duì)象接收消息,同時(shí)向具體的同事對(duì)象發(fā)出命令。
Colleague:抽象同事類(lèi)角色,定義了中介者對(duì)象的接口,只知道中介而不知道其他同事對(duì)象。
ConcreteColleagueA,ConcreteColleagueB:具體的同事類(lèi)角色,每個(gè)具體同事類(lèi)都知道本身在小范圍內(nèi)的行為,而不知道他在大范圍中的行為。
模板代碼:
抽象的中介者:
public interface Mediator {void change(); }具體的中介者:
public class ConcreteMediator implements Mediator {public ConcreteColleagueA concreteColleagueA;public ConcreteColleagueB concreteColleagueB;public void setConcreteColleagueA(ConcreteColleagueA concreteColleagueA) {this.concreteColleagueA = concreteColleagueA;}public void setConcreteColleagueB(ConcreteColleagueB concreteColleagueB) {this.concreteColleagueB = concreteColleagueB;}@Overridepublic void change() {concreteColleagueA.action();concreteColleagueB.action();} }抽象的同事:
public abstract class Colleague {public Mediator mediator;public Colleague(Mediator mediator) {this.mediator = mediator;}public abstract void action(); }具體的同事A:
public class ConcreteColleagueA extends Colleague {public ConcreteColleagueA(Mediator mediator) {super(mediator);}@Overridepublic void action() {System.out.println("交給中介做A的事情");} }具體的同事B:
public class ConcreteColleagueB extends Colleague {public ConcreteColleagueB(Mediator mediator) {super(mediator);}@Overridepublic void action() {System.out.println("交給中介做B的事情");} }五、簡(jiǎn)單示例
在電腦中,主機(jī)部分主要分為:CPU、內(nèi)存、顯卡、IO設(shè)備,而將它們整合起來(lái)的就是主板,這里主板就是一個(gè)中介者。以此為例。
抽象中介者:
public abstract class Mediator {/*** 同事對(duì)象改變時(shí)通知中介者的方法* 在同事對(duì)象改變時(shí)由中介者去通知其他的同事對(duì)象* * @param c 同事對(duì)象*/public abstract void changed(Colleague c); }抽象同事:
public abstract class Colleague {protected Mediator mediator;//每一個(gè)同事都該知道其中介者public Colleague(Mediator mediator) {this.mediator = mediator;}}CPU同事:
public class CPU extends Colleague{private String dataVideo, dataSound; //視頻和音頻數(shù)據(jù)public CPU(Mediator mediator) {super(mediator);}/*** 獲取視頻數(shù)據(jù)* * @return 視頻數(shù)據(jù)*/public String getDataVideo(){return dataVideo;}/*** 獲取音頻數(shù)據(jù)* * @return 音頻數(shù)據(jù)*/public String getDataSound(){return dataSound;}/*** 解碼數(shù)據(jù)* * @param data音、視頻數(shù)據(jù)*/public void decodeData(String data){//分割音、視頻數(shù)據(jù)String[] tmp = data.split(",");//解析音、視頻數(shù)據(jù)dataVideo = tmp[0];dataSound = tmp[1];//告訴中介者自身狀態(tài)改變mediator.changed(this);} }光驅(qū)同事:
public class CDDevice extends Colleague{private String data; //視頻數(shù)據(jù)public CDDevice(Mediator mediator) {super(mediator);}/*** 讀取視頻數(shù)據(jù)* * @return 視頻數(shù)據(jù)*/public String read(){return data;}/*** 加載視頻數(shù)據(jù)* * @return 音頻數(shù)據(jù)*/public void load(){data = "視頻數(shù)據(jù),音頻數(shù)據(jù)";//告訴中介者自身狀態(tài)改變mediator.changed(this);} }顯卡同事:
public class GraphicsCard extends Colleague{public GraphicsCard(Mediator mediator) {super(mediator);}/*** 播放視頻數(shù)據(jù)* * @param 視頻數(shù)據(jù)*/public void videoPlay(String data){System.out.println("視頻:" + data);} }聲卡同事:
public class SoundCard extends Colleague{public SoundCard(Mediator mediator) {super(mediator);}/*** 播放音頻數(shù)據(jù)* * @param 音頻數(shù)據(jù)*/public void soundPlay(String data){System.out.println("音頻:" + data);} }主板中介者:
public class MainBoard extends Mediator{private CDDevice cdDevice; //光驅(qū)設(shè)備private CPU cpu; //CPUprivate SoundCard soundCard; //聲卡設(shè)備private GraphicsCard graphicsCard; //顯卡設(shè)備@Overridepublic void changed(Colleague c) {//如果光驅(qū)讀取了數(shù)據(jù)if(c == cdDevice){handleCD((CDDevice) c);}//如果CPU處理完數(shù)據(jù)else if(c == cpu){handleCD((CPU) c);}}/*** 處理光驅(qū)讀取數(shù)據(jù)后與其他設(shè)備的交互* * @param cdDevice 光驅(qū)設(shè)備*/public void handleCD(CDDevice cdDevice){cpu.decodeData(cdDevice.read());}/*** 處理CPU讀取數(shù)據(jù)后與其他設(shè)備的交互* * @param cpu CPU*/public void handleCD(CPU cpu){soundCard.soundPlay(cpu.getDataSound());graphicsCard.videoPlay(cpu.getDataVideo());}/*** 設(shè)置CD設(shè)備* * @param CDDevice CD設(shè)備*/public void setCDDevice(CDDevice cdDevice){this.cdDevice = cdDevice;}/*** 設(shè)置CPU* * @param cpu CPU*/public void setCPU(CPU cpu){this.cpu = cpu;}/*** 設(shè)置聲卡設(shè)備* * @param soundCard 聲卡設(shè)備*/public void setSoundCard(SoundCard soundCard){this.soundCard = soundCard;}/*** 設(shè)置顯卡設(shè)備* * @param graphicsCard 顯卡設(shè)備*/public void setGraphicsCard(GraphicsCard graphicsCard){this.graphicsCard = graphicsCard;} }播放電影:
public class Client {public static void main(String[] args) {//構(gòu)造主板對(duì)象MainBoard mediator = new MainBoard();//分別構(gòu)造各個(gè)零件CDDevice cd = new CDDevice(mediator);CPU cpu = new CPU(mediator);GraphicsCard gc = new GraphicsCard(mediator);SoundCard sc = new SoundCard(mediator);//將各個(gè)零件安裝到主板mediator.setCDDevice(cd);mediator.setCPU(cpu);mediator.setGraphicsCard(gc);mediator.setSoundCard(sc);//播放電影cd.load();}}結(jié)果:
音頻:音頻數(shù)據(jù) 視頻:視頻數(shù)據(jù)可以看出中介者模式將多對(duì)多的相互作用轉(zhuǎn)化為一對(duì)多的相互作用,將系統(tǒng)從網(wǎng)狀結(jié)構(gòu)變?yōu)橐灾薪檎邽橹行牡男切谓Y(jié)構(gòu)(這里就是主板),達(dá)到降低系統(tǒng)的復(fù)雜性,提高可擴(kuò)展性。
六、Android源碼中的中介者模式
1、Keyguard解鎖屏
詳細(xì)機(jī)制參考:Android4.0 Keyguard解鎖屏機(jī)制
七、總結(jié)
其實(shí)在Android開(kāi)發(fā)中我們可能無(wú)意間就使用了中介者模式,比如登錄注冊(cè)界面,我們使用EditText的addTextChangedListener監(jiān)聽(tīng)輸入密碼的位數(shù)、用戶名是否為空,密碼與確認(rèn)密碼是否一致等等判斷時(shí),此時(shí)多個(gè)控件交互,就是由Activity充當(dāng)中介者來(lái)協(xié)調(diào)。
優(yōu)點(diǎn):
適當(dāng)?shù)厥褂弥薪檎吣J娇梢员苊馔骂?lèi)之間的過(guò)度耦合,使得各同事類(lèi)之間可以相對(duì)獨(dú)立地使用。
使用中介者模式可以將對(duì)象的行為和協(xié)作進(jìn)行抽象,能夠比較靈活的處理對(duì)象間的相互作用。
使用中介者模式可以將對(duì)象間多對(duì)多的關(guān)聯(lián)轉(zhuǎn)變?yōu)橐粚?duì)多的關(guān)聯(lián),使對(duì)象間的關(guān)系易于理解和維護(hù)。
缺點(diǎn):
- 中介者模式是一種比較常用的模式,也是一種比較容易被濫用的模式。對(duì)于大多數(shù)的情況,同事類(lèi)之間的關(guān)系不會(huì)復(fù)雜到混亂不堪的網(wǎng)狀結(jié)構(gòu),因此,大多數(shù)情況下,將對(duì)象間的依賴關(guān)系封裝的同事類(lèi)內(nèi)部就可以的,沒(méi)有必要非引入中介者模式。濫用中介者模式,只會(huì)讓事情變的更復(fù)雜。所以,我們決定使用中介者模式之前要多方考慮、權(quán)衡利弊。
總結(jié)
以上是生活随笔為你收集整理的Android设计模式之——中介者模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: c++面向对象高级编程 学习十二 模板
- 下一篇: Android中List、Set、Map