中介者模式
面向對象設計鼓勵將行為分佈到各個對像中, 這種分佈可能會導致對象間有許多連接. 在最壞的情況下, 每一個對像都需要知道其他所有對象.
雖然將一個系統分割成許多對象可增強可復用性, 但是對象間相互連接的激增又會降低其可復用性. 大量的連接關係使得一個對像不可能在沒有其他對象的協助下工作(系統表現為一個不可分割的整體), 此時再對系統行為進行任何較大改動就十分困難. 因為行為被分佈在許多對像中, 結果是不得不定義很多子類以定制系統的行為. 由此我們引入了中介者物件Mediator:
透過中介者物件, 可以將網狀結構的系統改造成以中介者為中心的星型結構, 每個具體物件不再與另一個物件直接發生關係, 而是透過中介者對象從中調停.中介者對象的引入,也使得系統結構不會因新對象的引入造成大量的修改.
中介者模式: 又稱調停者模式, 用一個中介者對象(Mediator)來封裝一系列物件的互動, 使各物件不需再顯示地相互引用, 從而使耦合鬆散, 而且可以獨立地改變他們之間的交互:
(圖片來源: 設計模式:可重複使用物件導向軟體的基礎)Tips: 各Colleague只知道Mediator的存在, 並不需要知道其他Colleague是否存在(不然怎麼解耦呢), 它只需將訊息發送給Mediator, 然後由Mediator轉發給其他Colleague(由Mediator存儲所有Colleague關係, 也只有Mediator知道有多少/哪些Colleague).
模式實現
聯合國轉發各國聲明, 調停各國關係:
各國向聯合國安理會發送和接收消息, 安理會在各國間'適當地'轉發請求以實現協作行為:
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
具體中介者:
•了解並維護它的各個同事;
•透過協調各同事對象實現協作行為(從同事接收訊息, 向具體同事發出命令).
class UnitedNationsSecurityCouncil extends UnitedNations { /** * 安理会在中间作出调停 * * @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); } } } }
如果不存在擴展情況, 向具體同事發出命令).
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("我们强烈谴责!!!"); System.out.println("----------"); iraq.declare("来呀, 来互相伤害呀!!!"); } }
•Client
rrreee----------------------------------------- ---------------------------------------
小結
•適用性
中介者模式很容易在系統中應用, 也很容易在系統中誤用. 當系統出現了「多對多」交互複雜的對象群時, 不要急於使用中介者, 最好首先先反思系統的設計是否是合理. 由於ConcreteMediator控制了集中化, 於是就把交互複雜性變成了中介者的複雜性, 使得中介者變得比任一個ConcreteColleague都複雜. 在下列情況下建議使用中介者模式:
◦一組對像以定義良好但複雜的方式進行通信. 產生的相互依賴關係結構混亂且難以理解.
•相關模式
◦Facade與中介者的不同之處在於它是對一個對象子系統進行抽象, 從而提供了一個更為方便的接口, 它的協議是單向的, 即Facade對象對這個子系統類別提出請求, 但反之則不可. 相反, Mediator提供了各Colleague物件不支援或不能支援的協作行為, 而且協定是多向的.
◦Colleague可使用Observer模式與Mediator通訊.
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持PHP中文網。
更多java設計模式之中介者模式相關文章請關注PHP中文網!
相關文章: