首頁 Java java教程 java設計模式之中介者模式

java設計模式之中介者模式

Mar 18, 2017 am 11:56 AM

中介者模式

面向對象設計鼓勵將行為分佈到各個對像中, 這種分佈可能會導致對象間有許多連接. 在最壞的情況下, 每一個對像都需要知道其他所有對象. 

雖然將一個系統分割成許多對象可增強可復用性, 但是對象間相互連接的激增又會降低其可復用性. 大量的連接關係使得一個對像不可能在沒有其他對象的協助下工作(系統表現為一個不可分割的整體), 此時再對系統行為進行任何較大改動就十分困難. 因為行為被分佈在許多對像中, 結果是不得不定義很多子類以定制系統的行為. 由此我們引入了中介者物件Mediator: 

java設計模式之中介者模式

透過中介者物件, 可以將網狀結構的系統改造成以中介者為中心的星型結構, 每個具體物件不再與另一個物件直接發生關係, 而是透過中介者對象從中調停.中介者對象的引入,也使得系統結構不會因新對象的引入造成大量的修改.

中介者模式: 又稱調停者模式, 用一個中介者對象(Mediator)來封裝一系列物件的互動, 使各物件不需再顯示地相互引用, 從而使耦合鬆散, 而且可以獨立地改變他們之間的交互: 

java設計模式之中介者模式

(圖片來源: 設計模式:可重複使用物件導向軟體的基礎)Tips: 各Colleague只知道Mediator的存在, 並不需要知道其他Colleague是否存在(不然怎麼解耦呢), 它只需將訊息發送給Mediator, 然後由Mediator轉發給其他Colleague(由Mediator存儲所有Colleague關係, 也只有Mediator知道有多少/哪些Colleague).

模式實現

聯合國轉發各國聲明, 調停各國關係: 
各國向聯合國安理會發送和接收消息, 安理會在各國間'適當地'轉發請求以實現協作行為:

java設計模式之中介者模式

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("来呀, 来互相伤害呀!!!");
 }
}
登入後複製
如果不存在擴展情況, 可與ConcreteMediator合二為一.

 •Client 

rrreee

----------------------------------------- ---------------------------------------

 小結

Mediator的出現減少了各Colleague之間的耦合, 使得可以獨立改變和復用各Colleague和Mediator, 由於把對像如何協作進行了抽象、將中介作為一個獨立的概念並將其封裝在一個對像中, 這樣關注的焦點就從對象各自本身的行為轉移到它們之間的交互上來, 從而可以站在一個更宏觀的角度去看待系統.



 •適用性 
中介者模式很容易在系統中應用, 也很容易在系統中誤用. 當系統出現了「多對多」交互複雜的對象群時, 不要急於使用中介者, 最好首先先反思系統的設計是否是合理. 由於ConcreteMediator控制了集中化, 於是就把交互複雜性變成了中介者的複雜性, 使得中介者變得比任一個ConcreteColleague都複雜. 在下列情況下建議使用中介者模式:
◦一組對像以定義良好但複雜的方式進行通信. 產生的相互依賴關係結構混亂且難以理解.

 ◦一個對象引用其他很多對象並且直接與這些對象通信, 導致難以復用該對象.🎜 ◦想定制一個分佈在多個類中的行為, 而又不想生成太多的子類.🎜

•相關模式
◦Facade與中介者的不同之處在於它是對一個對象子系統進行抽象, 從而提供了一個更為方便的接口, 它的協議是單向的, 即Facade對象對這個子系統類別提出請求, 但反之則不可. 相反, Mediator提供了各Colleague物件不支援或不能支援的協作行為, 而且協定是多向的.
 ◦Colleague可使用Observer模式與Mediator通訊.

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持PHP中文網。

更多java設計模式之中介者模式相關文章請關注PHP中文網!

相關文章:

Java實作中介者(Mediator)模式的程式碼具體介紹

Java設計模式之責任鏈模式簡介

設計模式代理模式(Proxy模式)介紹模式。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1665
14
CakePHP 教程
1424
52
Laravel 教程
1321
25
PHP教程
1269
29
C# 教程
1249
24
公司安全軟件導致應用無法運行?如何排查和解決? 公司安全軟件導致應用無法運行?如何排查和解決? Apr 19, 2025 pm 04:51 PM

公司安全軟件導致部分應用無法正常運行的排查與解決方法許多公司為了保障內部網絡安全,會部署安全軟件。 ...

如何將姓名轉換為數字以實現排序並保持群組中的一致性? 如何將姓名轉換為數字以實現排序並保持群組中的一致性? Apr 19, 2025 pm 11:30 PM

將姓名轉換為數字以實現排序的解決方案在許多應用場景中,用戶可能需要在群組中進行排序,尤其是在一個用...

如何使用MapStruct簡化系統對接中的字段映射問題? 如何使用MapStruct簡化系統對接中的字段映射問題? Apr 19, 2025 pm 06:21 PM

系統對接中的字段映射處理在進行系統對接時,常常會遇到一個棘手的問題:如何將A系統的接口字段有效地映�...

IntelliJ IDEA是如何在不輸出日誌的情況下識別Spring Boot項目的端口號的? IntelliJ IDEA是如何在不輸出日誌的情況下識別Spring Boot項目的端口號的? Apr 19, 2025 pm 11:45 PM

在使用IntelliJIDEAUltimate版本啟動Spring...

如何優雅地獲取實體類變量名構建數據庫查詢條件? 如何優雅地獲取實體類變量名構建數據庫查詢條件? Apr 19, 2025 pm 11:42 PM

在使用MyBatis-Plus或其他ORM框架進行數據庫操作時,經常需要根據實體類的屬性名構造查詢條件。如果每次都手動...

Java對像如何安全地轉換為數組? Java對像如何安全地轉換為數組? Apr 19, 2025 pm 11:33 PM

Java對象與數組的轉換:深入探討強制類型轉換的風險與正確方法很多Java初學者會遇到將一個對象轉換成數組的�...

電商平台SKU和SPU數據庫設計:如何兼顧用戶自定義屬性和無屬性商品? 電商平台SKU和SPU數據庫設計:如何兼顧用戶自定義屬性和無屬性商品? Apr 19, 2025 pm 11:27 PM

電商平台SKU和SPU表設計詳解本文將探討電商平台中SKU和SPU的數據庫設計問題,特別是如何處理用戶自定義銷售屬...

如何利用Redis緩存方案高效實現產品排行榜列表的需求? 如何利用Redis緩存方案高效實現產品排行榜列表的需求? Apr 19, 2025 pm 11:36 PM

Redis緩存方案如何實現產品排行榜列表的需求?在開發過程中,我們常常需要處理排行榜的需求,例如展示一個�...

See all articles