java設(shè)計模式之中介者模式
中介者模式
面向?qū)ο笤O(shè)計鼓勵將行為分布到各個對象中, 這種分布可能會導(dǎo)致對象間有許多連接. 在最壞的情況下, 每一個對象都需要知道其他所有對象.
雖然將一個系統(tǒng)分割成許多對象可增強可復(fù)用性, 但是對象間相互連接的激增又會降低其可復(fù)用性. 大量的連接關(guān)系使得一個對象不可能在沒有其他對象的協(xié)助下工作(系統(tǒng)表現(xiàn)為一個不可分割的整體), 此時再對系統(tǒng)行為進行任何較大改動就十分困難. 因為行為被分布在許多對象中, 結(jié)果是不得不定義很多子類以定制系統(tǒng)的行為. 由此我們引入了中介者對象Mediator:
通過中介者對象, 可以將網(wǎng)狀結(jié)構(gòu)的系統(tǒng)改造成以中介者為中心的星型結(jié)構(gòu), 每個具體對象不再與另一個對象直接發(fā)生關(guān)系, 而是通過中介者對象從中調(diào)停.中介者對象的引入,也使得系統(tǒng)結(jié)構(gòu)不會因新對象的引入造成大量的修改.
中介者模式: 又稱調(diào)停者模式, 用一個中介者對象(Mediator)來封裝一系列對象的交互, 使各對象不需再顯示地相互引用, 從而使耦合松散, 而且可以獨立地改變他們之間的交互:
(圖片來源: 設(shè)計模式: 可復(fù)用面向?qū)ο筌浖幕A(chǔ))Tips: 各Colleague只知道Mediator的存在, 并不需要知道其他Colleague是否存在(不然怎么解耦呢), 它只需將消息發(fā)送給Mediator, 然后由Mediator轉(zhuǎn)發(fā)給其他Colleague(由Mediator存儲所有Colleague關(guān)系, 也只有Mediator知道有多少/哪些Colleague).
模式實現(xiàn)
聯(lián)合國轉(zhuǎn)發(fā)各國聲明, 調(diào)停各國關(guān)系:
各國向聯(lián)合國安理會發(fā)送和接收消息, 安理會在各國間'適當(dāng)?shù)?轉(zhuǎn)發(fā)請求以實現(xiàn)協(xié)作行為:
Colleague
抽象同事類, 定義各同事的公有方法:
/** * @author jifang * @since 16/8/28 下午4:22. */ public abstract class Country { protected UnitedNations mediator; private String name; public Country(UnitedNations mediator, String name) { this.mediator = mediator; this.name = name; } public String getName() { return name; } protected abstract void declare(String msg); protected abstract void receive(String msg); }
--------------------------------------------------------------------------------
ConcreteColleague
具體同事類:
•每一個同事類都知道它的中介者對象.
•每一個同事對象在需與其他同事通信時, 與它的中介者通信.
class USA extends Country { public USA(UnitedNations mediator, String name) { super(mediator, name); } @Override public void declare(String msg) { mediator.declare(this, msg); } @Override public void receive(String msg) { System.out.println("美國接收到: [" + msg + "]"); } } class Iraq extends Country { public Iraq(UnitedNations mediator, String name) { super(mediator, name); } @Override public void declare(String msg) { mediator.declare(this, msg); } @Override public void receive(String msg) { System.out.println("伊拉克接收到: [" + msg + "]"); } } class China extends Country { public China(UnitedNations mediator, String name) { super(mediator, name); } @Override public void declare(String msg) { mediator.declare(this, msg); } @Override public void receive(String msg) { System.out.println("中國接收到: [" + msg + "]"); } }
--------------------------------------------------------------------------------
Mediator
抽象中介者: 定義一個接口用于與各同事對象通信:
public abstract class UnitedNations { protected List<Country> countries = new LinkedList<>(); public void register(Country country) { countries.add(country); } public void remove(Country country) { countries.remove(country); } protected abstract void declare(Country country, String msg); }
--------------------------------------------------------------------------------
ConcreteMediator
具體中介者:
•了解并維護它的各個同事;
•通過協(xié)調(diào)各同事對象實現(xiàn)協(xié)作行為(從同事接收消息, 向具體同事發(fā)出命令).
class UnitedNationsSecurityCouncil extends UnitedNations { /** * 安理會在中間作出調(diào)停 * * @param country * @param msg */ @Override protected void declare(Country country, String msg) { for (Country toCountry : countries) { if (!toCountry.equals(country)) { String name = country.getName(); toCountry.receive(name + "平和的說: " + msg); } } } }
如果不存在擴展情況, 那么Mediator可與ConcreteMediator合二為一.
•Client
public class Client { @Test public void client() { UnitedNations mediator = new UnitedNationsSecurityCouncil(); Country usa = new USA(mediator, "美國"); Country china = new China(mediator, "中國"); Country iraq = new Iraq(mediator, "伊拉克"); mediator.register(usa); mediator.register(china); mediator.register(iraq); usa.declare("我要打伊拉克, 誰管我跟誰急!!!"); System.out.println("----------"); china.declare("我們強烈譴責(zé)!!!"); System.out.println("----------"); iraq.declare("來呀, 來互相傷害呀!!!"); } }
小結(jié)
Mediator的出現(xiàn)減少了各Colleague之間的耦合, 使得可以獨立改變和復(fù)用各Colleague和Mediator, 由于把對象如何協(xié)作進行了抽象、將中介作為一個獨立的概念并將其封裝在一個對象中, 這樣關(guān)注的焦點就從對象各自本身的行為轉(zhuǎn)移到它們之間的交互上來, 從而可以站在一個更宏觀的角度去看待系統(tǒng).
•適用性
中介者模式很容易在系統(tǒng)中應(yīng)用, 也很容易在系統(tǒng)中誤用. 當(dāng)系統(tǒng)出現(xiàn)了“多對多”交互復(fù)雜的對象群時, 不要急于使用中介者, 最好首先先反思系統(tǒng)的設(shè)計是否是合理. 由于ConcreteMediator控制了集中化, 于是就把交互復(fù)雜性變成了中介者的復(fù)雜性, 使得中介者變得比任一個ConcreteColleague都復(fù)雜. 在下列情況下建議使用中介者模式:
◦一組對象以定義良好但復(fù)雜的方式進行通信. 產(chǎn)生的相互依賴關(guān)系結(jié)構(gòu)混亂且難以理解.
◦一個對象引用其他很多對象并且直接與這些對象通信, 導(dǎo)致難以復(fù)用該對象.
◦想定制一個分布在多個類中的行為, 而又不想生成太多的子類.
•相關(guān)模式
◦Facade與中介者的不同之處在于它是對一個對象子系統(tǒng)進行抽象, 從而提供了一個更為方便的接口, 它的協(xié)議是單向的, 即Facade對象對這個子系統(tǒng)類提出請求, 但反之則不可. 相反, Mediator提供了各Colleague對象不支持或不能支持的協(xié)作行為, 而且協(xié)議是多向的.
◦Colleague可使用Observer模式與Mediator通信.
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
詳解Java面向?qū)ο笾鄳B(tài)的原理與實現(xiàn)
多態(tài)是指不同的子類在繼承父類后分別都重寫覆蓋了父類的方法,即父類同一個方法,在繼承的子類中表現(xiàn)出不同的形式。本文將詳解多態(tài)的原理與實現(xiàn),感興趣的可以學(xué)習(xí)一下2022-05-05mybatis(mybatis-plus)映射文件(XML文件)中特殊字符轉(zhuǎn)義的實現(xiàn)
XML 文件在解析時會將五種特殊字符進行轉(zhuǎn)義,本文主要介紹了mybatis(mybatis-plus)映射文件(XML文件)中特殊字符轉(zhuǎn)義的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下2023-12-12MyBatis與SpringMVC相結(jié)合實現(xiàn)文件上傳、下載功能
這篇文章主要介紹了MyBatis與SpringMVC相結(jié)合實現(xiàn)文件上傳、下載功能的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-06-06springboot+thymeleaf找不到視圖的解決方案
這篇文章主要介紹了springboot+thymeleaf找不到視圖的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06