Adapter Pattern 介紹及 JavaScript 實作
轉接器模式(Adapter Pattern)是一種結構型設計模式(Structural Design Pattern),其目的是在解決不同介面(interface)之間遇到的溝通問題。這篇文章便是在跟各位介紹轉接器模式的概念及實作。
概念
在開發程式碼的過程中,一定會遇到需要跟第三方串接、或是跟我們無法掌控的內部服務串接的情況。在一開始串接的時候,因為只有單一情境會使用到,所以我們的程式碼可能會像是:
因為只有單一功能會使用到,所以也不會有什麼問題。但隨著產品服務的增長,會串接該服務的功能可能越來越多,這時候就有可能會變成:
這個時候如果第三方服務有什麼改動的時候(例如某個欄位或函式換名字了),就會需要在多個程式碼裡修改它。原本調整程式碼只需要做一次,隨著串接第三方服務的程式碼變多,需要修改時所花的時間成本也跟著增加,甚至還可能漏改。因此我們可以將需要串接第三方服務的部分改成單一介面:
這樣子單一窗口的設計可以幫助我們建立易維護的程式碼,如果發生上述第三方服務有改動的情況,只要修改一支檔案——也就是修改 Adapter 就可以繼續運作了。
抑或者是,今天產品同時有新舊不同版本的相同服務正在運行中,且新舊服務會使用的欄位或格式不盡相同,在把舊有服務全面切換成新服務之前,勢必會有一段新舊並存的過渡期,此時就會需要透過 Adapter 的轉換,來讓該服務跟其他功能正常串接。
舉例來說:會員資料的結構有推出新的版本,但網頁呈現上還沒有跟著換新,此時新版的會員資料就需要透過 Adapter 先做處理,轉換成原本網頁能看得懂的資料格式。在未來網頁呈現跟著改動後,再將 Adapter 移除,讓新版網頁跟新版會員資料照原本期望的方式互相溝通。
更進一步,在建立起與 Adapter 串接的介面之後,App core code 也可以利用相同的格式,利用各種不同的 Adapter 去串接更多的第三方服務:
實作
這次的實作練習是以串接兩家不同的天氣資訊 API 為例。
公司的服務原本有串接一家名為「WeatherAPI」的服務,現有的程式碼如下:
在範例裡,「WeatherAPI」就是我們無法控制的第三方服務,「dashboard.js」就是 App core code。
今天發現產品的需求是要將串接的服務從「WeatherAPI」改為「OpenWeather」,如下:
此時發現有幾個問題:
- OpenWeather 裡取得氣溫的 method 稱作「getCurrent」,原本使用 WeatherAPI 時對應的 method 叫做「getWeather」。
- OpenWeather 的 getCurrent 要傳入的參數不是城市的字串,而是帶有 city 的 key 的物件。
- OpenWeather 並不會回傳城市資料。
- getCurrent 回傳的氣溫是華氏,我們需要的是攝氏。
- 如果要修改這些資訊,可以在 dashboard.js 直接修改沒錯。但如果有多個像是 dashboard.js 這樣的檔案正在使用 WeatherAPI 的話,修改的成本就會非常高。
我們可以做的是先建立 OpenWeather 的 Adapter——OpenWeatherAdapter,接著再將原先引用 WeatherAPI 的部分,改為引用 OpenWeatherAdapter,實作如下:
而修改後的 dashboard.js 程式碼如下:
以上就是一個簡單的 Adapter Pattern 的實作範例。如果有任何的疑問或是敘述錯誤的地方,也都歡迎留言與我交流討論😃。