javascript設計模式——適配器模式

来源:http://www.cnblogs.com/xiaohuochai/archive/2017/12/17/8047359.html
-Advertisement-
Play Games

前面的話 適配器模式的作用是解決兩個軟體實體間的介面不相容的問題。使用適配器模式之後,原本由於介面不相容而不能工作的兩個軟體實體可以一起工作。適配器的別名是包裝器(wrapper),這是一個相對簡單的模式。在程式開發中有許多這樣的場景:當試圖調用模塊或者對象的某個介面時,卻發現這個介面的格式並不符合 ...


前面的話

  適配器模式的作用是解決兩個軟體實體間的介面不相容的問題。使用適配器模式之後,原本由於介面不相容而不能工作的兩個軟體實體可以一起工作。適配器的別名是包裝器(wrapper),這是一個相對簡單的模式。在程式開發中有許多這樣的場景:當試圖調用模塊或者對象的某個介面時,卻發現這個介面的格式並不符合目前的需求。這時候有兩種解決辦法,第一種是修改原來的介面實現,但如果原來的模塊很複雜,或者拿到的模塊是一段別人編寫的經過壓縮的代碼,修改原介面就顯得不太現實了。第二種辦法是創建一個適配器,將原介面轉換為客戶希望的另一個介面,客戶只需要和適配器打交道。本文將詳細介紹適配器模式

 

現實中的適配器

  適配器在現實生活的應用非常廣泛,接下來來看幾個現實生活中的適配器模式

  1、港式插頭轉換器

  港式的電器插頭比大陸的電器插頭體積要大一些。如果從香港買了一個Macbook,會發現充電器無法插在家裡的插座上,為此而改造家裡的插座顯然不方便,所以需要一個適配器:

  2、電源適配器

  Macbook電池支持的電壓是20V,日常生活中的交流電壓一般是220V。除了瞭解的220V交流電壓,日本和南韓的交流電壓大多是100V,而英國和澳大利亞的是240V。筆記本電腦的電源適配器就承擔了轉換電壓的作用,電源適配器使筆記本電腦在100V~240V的電壓之內都能正常工作,這也是它為什麼被稱為電源“適配器”的原因

  3、USB轉介面

  在以前的電腦上,PS2介面是連接滑鼠、鍵盤等其他外部設備的標準介面。但隨著技術的發展,越來越多的電腦開始放棄了PS2介面,轉而僅支持USB介面。所以那些過去生產出來的只擁有PS2介面的滑鼠、鍵盤、游戲手柄等,需要一個USB轉介面才能繼續正常工作,這是PS2-USB適配器誕生的原因

 

應用

  如果現有的介面已經能夠正常工作,那就永遠不會用上適配器模式。適配器模式是一種“亡羊補牢”的模式,沒有人會在程式的設計之初就使用它。因為沒有人可以完全預料到未來的事情,也許現在好好工作的介面,未來的某天卻不再適用於新系統,那麼可以用適配器模式把舊介面包裝成一個新的介面,使它繼續保持生命力。比如在JSON格式流行之前,很多cgi返回的都是XML格式的數據,如果今天仍然想繼續使用這些介面,顯然可以創造一個XML-JSON的適配器

  下麵是一個實例,向googleMap和baiduMap都發出“顯示”請求時,googleMap和baiduMap分別以各自的方式在頁面中展現了地圖:

var googleMap = {
    show: function(){
        console.log( '開始渲染谷歌地圖' );
    }
};
var baiduMap = {
    show: function(){
        console.log( '開始渲染百度地圖' );
    }
};
var renderMap = function( map ){
    if ( map.show instanceof Function ){
        map.show();
    }
};

renderMap( googleMap ); // 輸出:開始渲染谷歌地圖
renderMap( baiduMap ); // 輸出:開始渲染百度地圖

  這段程式得以順利運行的關鍵是googleMap和baiduMap提供了一致的show方法,但第三方的介面方法並不在控制範圍之內,假如baiduMap提供的顯示地圖的方法不叫show而叫display呢?

  baiduMap這個對象來源於第三方,正常情況下都不應該去改動它。此時可以通過增加baiduMapAdapter來解決問題:

var googleMap = {
    show: function(){
        console.log( '開始渲染谷歌地圖' );
    }
};
var baiduMap = {
    display: function(){
        console.log( '開始渲染百度地圖' );
    }
};
var baiduMapAdapter = {
    show: function(){
        return baiduMap.display();

    }
};

renderMap( googleMap ); // 輸出:開始渲染谷歌地圖
renderMap( baiduMapAdapter ); // 輸出:開始渲染百度地圖

  再看看另一個例子。假設正在編寫一個渲染北京市地圖的頁面。目前從第三方資源里獲得了北京市的所有地區以及它們所對應的ID,並且成功地渲染到頁面中:

var getBeijingCity = function(){
    var beijingCity = [
    {
        name: 'chaoyang',
        id: 11,
    }, {
        name: 'haidian',
        id: 12,
    }
    ];
    return beijingCity;
};
var render = function( fn ){
    console.log( '開始渲染北京市地圖' );
    document.write( JSON.stringify( fn() ) );
};
render( getBeijingCity );

  利用這些數據,編寫完成了整個頁面,並且線上上穩定地運行了一段時間。但後來發現這些數據不太可靠,裡面還缺少很多地區。於是又在網上找到了另外一些數據資源,這次的數據更加全面,但遺憾的是,數據結構和正運行在項目中的並不一致。新的數據結構如下:

var BeijingCity = {
    chaoyang: 11,
    haidian: 12,
    pinggu: 13
};

  除了大動干戈地改寫渲染頁面的前端代碼之外,另外一種更輕便的解決方式就是新增一個數據格式轉換的適配器:

var getBeijingCity = function(){
    var beijingCity = [
    {
        name: 'chaoyang',
        id: 11,
    }, {
        name: 'haidian',
        id: 12,
    }

    ];
    return beijingCity;
};
var render = function( fn ){
    console.log( '開始渲染北京市地圖' );
    document.write( JSON.stringify( fn() ) );
};
var addressAdapter = function( oldAddressfn ){
    var address = {},
    oldAddress = oldAddressfn();
    for ( var i = 0, c; c = oldAddress[ i++ ]; ){
        address[ c.name ] = c.id;
    }
    return function(){
        return address;
    }
};
render( addressAdapter( getBeijingCity ) );

  那麼接下來需要做的,就是把代碼中調用getBeijingCity的地方,用經過addressAdapter適配器轉換之後的新函數來代替

 

總結

  適配器模式是一對相對簡單的模式。有一些模式跟適配器模式的結構非常相似,比如裝飾者模式、代理模式和外觀模式。這幾種模式都屬於“包裝模式”,都是由一個對象來包裝另一個對象。區別它們的關鍵仍然是模式的意圖。適配器模式主要用來解決兩個已有介面之間不匹配的問題,它不考慮這些介面是怎樣實現的,也不考慮它們將來可能會如何演化。適配器模式不需要改變已有的介面,就能夠使它們協同作用。裝飾者模式和代理模式也不會改變原有對象的介面,但裝飾者模式的作用是為了給對象增加功能。裝飾者模式常常形成一條長的裝飾鏈,而適配器模式通常只包裝一次。代理模式是為了控制對對象的訪問,通常也只包裝一次。外觀模式的作用倒是和適配器比較相似,有人把外觀模式看成一組對象的適配器,但外觀模式最顯著的特點是定義了一個新的介面

 

 

 


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

-Advertisement-
Play Games
更多相關文章
  • 小時候, 鄉愁是一枚小小的郵票, 我在這頭, 母親在那頭。 長大後,鄉愁是一張窄窄的船票, 我在這頭, 新娘在那頭。 後來啊, 鄉愁是一方矮矮的墳墓, 我在外頭, 母親在裡頭。 而現在, 鄉愁是一灣淺淺的海峽, 我在這頭, 大陸在那頭。 ——餘光中《鄉愁》 本文為讀 lodash 源碼的第三篇,後續 ...
  • 前面的話 面向對象的設計原則,可以說每種設計模式都是為了讓代碼迎合其中一個或多個原則而出現的, 它們本身已經融入了設計模式之中,給面向對象編程指明瞭方向。適合javascript開發的設計原則包括是單一職責原則、最少知識原則和開放封閉原則。本文將詳細介紹面向對象的設計原則 單一職責原則 就一個類而言 ...
  • 今天,給大家分享一個每一個程式員,或者說是碼農都會有的通病 自我懷疑。無論你的技術到達任何程度,如何任何境界,或許某一刻你的指尖會停頓,因為你的自我懷疑。 “你若想嘗試一下勇者的滋味,一定要像個真正的勇者一樣,豁出全部的力量去行動,這時你的恐懼心理將會為勇猛果敢所取代。”心理學家丘吉爾說得一句話。其 ...
  • Chimee是由奇舞團開源的一套H5視頻播放器解決方案,由奇舞團視頻雲前端團隊結合在業務和視頻編解碼方向的沉澱積累傾心打造。Chimee支持MP4、M3U8、FLV等多種媒體格式,同時它也幫我們解決了大部分的相容性、差異化問題,包括全屏、自動播放、內聯播放、直播解碼等常見媒體播放需求。 ...
  • 一、屬性相關 我們通常把特征(attribute)和屬性(property)統稱為屬性,但是他們確實是不同的概念,特征(attribute)會表現在HTML文本中,對特征的修改一定會表現在元素的outerHTML中,並且特征只存在於元素節點中;屬性(property)是對於JS對象進行修改,除了瀏覽 ...
  • 留存root javascript // Establish the root object, ( ) in the browser, // on the server, or in some virtual machines. We use // instead of for support. v ...
  • 時間:2017年12月17日 20:53:43 用於:個人總結 javascript知識點總結:1.獲取對象:document.getElementById("id")/document.getElementsTagName("li")2.事件 滑鼠事件: onclick 點擊 onmouseove ...
  • 性能分析。。。 window.performance.timing中相關屬性語義: 1.主要性能分析指標 一般指標: 實際前端更關註的指標(需要在實際中結合自身代碼): console.log('首屏圖片載入完成 : ',window.lastImgLoadTime - window.perform ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...