設計模式(五):中介者模式

来源:http://www.cnblogs.com/lovesong/archive/2016/06/11/5575594.html
-Advertisement-
Play Games

在《JavaScript設計模式》關於中介者模式的介紹里,裡面有些錯誤和擅自添加的例子,雖然例子(英文版沒有)是為了讓人更好理解,但是該篇章加上的例子卻給人誤導的感覺,所以如果有人讀這個章節時,建議看英文版。 在看這個模式時候,我只想弄明白一點,中介者模式與訂閱/發佈模式的區別在哪? 中介者模式定義 ...


在《JavaScript設計模式》關於中介者模式的介紹里,裡面有些錯誤和擅自添加的例子,雖然例子(英文版沒有)是為了讓人更好理解,但是該篇章加上的例子卻給人誤導的感覺,所以如果有人讀這個章節時,建議看英文版。

在看這個模式時候,我只想弄明白一點,中介者模式與訂閱/發佈模式的區別在哪?

中介者模式定義

中介者作為一種行為設計模式,它公開一個統一的介面,系統的不同對象或組件可以通過該介面進行通信。增加一個中介者對象後,所有的相關對象通過中介者對象來通信,而不是互相引用,所以當一個對象發生改變時,只需要通知中介者對象即可。

英文版:

When it comes to the Mediator and Event Aggregator patterns, there are some times where it may look like the patterns are interchangeable due to implementation similarities. However, the semantics and intent of these patterns are very different.

And even if the implementations both use some of the same core constructs, I believe there is a distinct difference between them. I also believe they should not be interchanged or confused in communication because of the differences.

中文版:

它也可能被認為是額外的或者是用於應用程式間的通知,如不同子系統之間的通信,這些子系統本身就很複雜,且可能希望通過發佈/訂閱關係實現內部組件間的解耦。

我:

首先我是不明白譯者為什麼不按英文版翻譯,另外還有一點譯文的意思根本就不是英文版的意思,我覺得不對。

我覺得是——中介者模式與事件訂閱模式有些時候看起來是可以互相替換的,因為它們的實現都差不多,但從語義和意圖上講,這些模式是各不相同的。即便是實現都用了相同的核心結構,我相信他們之間還是有區別,在通信時是不能互換和混淆。

PS:總結就是,兩個模式實現上有些相同,但意圖是不同的。

例子

簡述:

機場交通控制系統。控制塔處理飛機的起飛和降落,所有的通信都是控制塔控制的。

代碼:

//飛機
var Plane = function(name){
    this.name = name;
}
 
Plane.prototype.takeOff = function(){ //起飛
     ControlTower.takeOff(this);
}
 
Plane.prototype.sendMsg = function(toPlane, msg){ //飛機間發消息
     ControlTower.sendMsg(this, toPlane, msg);
}
 
Plane.prototype.receive = function(fromPlane, msg){
     console.log(this.name + "-收到來自-" + fromPlane.name + "消息:" + msg);
}
 
//飛機控制塔(中介者)
var ControlTower = (function(){
     //假設只有一條跑道,跑道只能起飛一隻飛機(不說降落)
     var onTrackPlaneName,
          canTrackUse = true;
    var takeOff = function(plane){
          if(!canTrackUse){
               console.log("跑道正在使用中...");
               return;
          }
          if(onTrackPlaneName == plane.name){
               console.log("您正在起飛中...");
            return;
          }
          canTrackUse = false;
          onTrackPlaneName = plane.name;
          console.log(plane.name + "正在起飛中...");
          setTimeout(function(){
               canTrackUse = true;
               onTrackPlaneName = null;
               console.log(plane.name + "已起飛...");
          }, 5000);
    }
    var sendMsg = function(from ,to , msg){
          to.receive(from, msg);
    }
 
    return {
        takeOff : takeOff,
        sendMsg : sendMsg
    }
})();
 
var p747 = new Plane('波音747');
var p666 = new Plane('飛豹666');
 
p747.takeOff();
p666.takeOff();
p747.sendMsg(p666, '開完飛機吃個飯麽');

適用場景

1. 一組定義良好的對象,現在要進行複雜的通信。

2. 定製一個分佈在多個類中的行為,而又不想生成太多的子類。

可以看出,中介對象主要是用來封裝行為的,行為的參與者就是那些對象,但是通過中介者,這些對象不用相互知道。(迪米特法則的具體實現)

優點

1. 中介者模式能夠將系統中對象或組件之間所需的通信渠道從多對多減少到多對一。

2. 符合迪米特原則。

迪米特法則(Law of Demeter)又叫作最少知識原則(Least Knowledge Principle 簡寫LKP),就是說一個對象應當對其他對象有儘可能少的瞭解,不和陌生人說話。

缺點

1. 中介者模式的缺點是顯而易見的,因為這個“中介“承擔了較多的責任,所以一旦這個中介對象出現了問題,那麼整個系統就會受到重大的影響。

中介者模式與觀察者模式差異

1. 調度中心不同。

中介者模式調度是由中介者,而觀察者模式調度的是觀察者;

中介者模式與訂閱/發佈模式的調度方式更像,都是獨立一個集中的調度中心。

2. 中介者模式參與了對象行為的實現(例如上面示例的飛機起飛),而觀察者模式並不參與,僅做目標通知。

中介者模式與訂閱/發佈模式差異

1. 中介者模式與業務相關,訂閱/發佈模式與業務無關。(這是我覺得最大差別)

雖然實現結構非常相像,但是很明顯的是,中介者模式參與業務相關東西,所以內容是大相徑庭的。

2. 兩個模式都有集中調度效果,對象之間不直接參与通信。 

 

參考文獻

1. 《Learning JavaScript Design Patterns》 by Addy Osmani

https://addyosmani.com/resources/essentialjsdesignpatterns/book/

2. 《JavaScript設計模式》by 徐濤【譯】

 

本文為原創文章,轉載請保留原出處,方便溯源,如有錯誤地方,謝謝指正。

本文地址 :http://www.cnblogs.com/lovesong/p/5575594.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在很多人的眼裡,C語言和linux常常是分不開的。這其中的原因很多,其中最重要的一部分我認為是linux本身就是C語言的傑出作品。當然,linux操作系統本身對C語言的支持也是相當到位的。作為一個真正的程式員來說,如果沒有在linux下麵用C語言編寫過完整的程式,那麼只能說他對C語言本身的理解還相關 ...
  • 客戶端: 1.服務端點 2.讀取客戶端已有的圖片數據 3.通過socket輸出流將數據發給服務端 4.讀取服務端反饋信息 5.關閉 獲取Socket對象,new出來,構造參數:String的服務端ip,int的埠號 調用Socket對象的getOutputStream()方法,得到OutputSt ...
  • J2SE 1.5提供了另一種形式的for迴圈。藉助這種形式的for迴圈,可以用更簡單地方式來遍曆數組和Collection等類型的對象。本文介紹使用這種迴圈的具體方式,說明如何自行定義能被這樣遍歷的類,並解釋和這一機制的一些常見問題。 在Java程式中,要“逐一處理”――或者說,“遍歷”――某一個數 ...
  • 本文是我閱讀周志明老師《深入理解Java虛擬機-JVM高級特性與最佳實戰》章節2.2的學習筆記。更多內容,請參考原書。 Java虛擬機在執行Java程式時會將其所管理的記憶體劃分為若幹個不同的數據區域,這些區域有各自的用途及生命周期。具體而言包括以下幾個區域。 1. 程式計數器 一塊較小的記憶體空間,可 ...
  • 原文地址:http://blog.csdn.net/cq361106306/article/details/38736551 synchronized--同步 顧名思義是用於同步互斥的作用的。 這裡精簡的記一下它的使用方法以及意義: 當synchronized修飾this或者非靜態方法或者是一個實例... ...
  • synchronized 關鍵字,它包括兩種用法:synchronized 方法和 synchronized 塊。 1. synchronized 方法:通過在方法聲明中加入 synchronized關鍵字來聲明 synchronized 方法。如:public synchronized void ...
  • △abstract不可以修飾成員變數 △一個類可以沒有抽象方法,可以定義為抽象類,這樣的目的是不能讓其他類建立本類對象,交給子類完成. △abstract和static(可以被類名調用方法,但是抽象方法調用沒有意義)final(不能被覆蓋方法)private(私有方法無法覆蓋) △介面只能被實現.被 ...
  • 首先介紹一款簡單利落的分頁利器:bootstrap-paginator 效果截圖: GitHub官方下載地址:https://github.com/lyonlai/bootstrap-paginator 備用下載地址:http://files.cnblogs.com/files/Dreamer-1/ ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...