什麼是適配器模式
將一個接口轉換成客戶希望的另一個接口,適配器模式使接口不兼容的那些類可以一起工作,其別名爲包裝器(Wrapper)
適配器的定義還是比較簡單,相信大家看上面的定義也可以看得懂,簡單來說,適配器就是把一個類的使用轉化爲客戶所期望的使用方式,適配使得因接口不兼容而不能在一起工作的類能在一起工作。
舉例說明
適配器模式在我們的應用中的使用非常廣泛,如果大家沒有注意過,那麼我在這裏爲大家舉一個生活中的例子。
像這種插頭轉換器大家應該都見過吧,國內的充電器插頭在國外並不能適用,所以我們需要一個轉換器(或者說是適配器)用於匹配國外的插槽。同樣的道理應用到我們的程序中,當我們的類(插頭)並不能適合用戶(插槽)使用的時候,我們就需要一個適配器來匹配這兩者之間的關係。
繪製UML類圖
針對上面的例子我們來繪製一下UML類圖
:
這就是JavaScript
中的適配器模式的UML
類圖,這個圖可能會與java
模式下的類圖有一定差距,這是因爲我們本課程內容爲前端中的設計模式在JavaScript
代碼中,並沒有接口這個概念,所以大家不要拿java
中的類圖來與這個比較。並且學習設計模式,最重要的是理解設計,理解模式,我們這裏的代碼也好,類圖也好,都是爲了讓大家能夠更好地理解原理。
OK
,回到我們的UML類圖
中,在上面的類圖中其實主要的就是兩個類,Adapter
表示我們的適配器,Target
表示需要被適配的目標類,當用戶去調用目標類的方法的時候 ,適配器需要做的是不改變用戶的調用方式,通過適配的方式來獲取用戶想要的結果。 打個具體的比方,比如說Target -> requrest
方法默認返回德國插槽,而我們需要的是一箇中國插槽,用戶不需要改變插插槽的方式,而是通過適配器來把德國插槽轉變爲中國插槽。
明白了,我們的原理邏輯之後,我們來看看一下代碼實現。
代碼實現
class Adapter {
adap () {
return "中國插槽"
}
}
class Target {
constructor () {
this.adapter = new Adapter();
}
request () {
return "德國插槽" + this.adapter.adap();
}
}
const target = new Target();
console.log(target.request());
我們實現的代碼非常簡單 , 首先request
方法默認返回的是一個德國插槽,我們借用適配器Adapter
來把Target
做了一層轉換,把德國插槽轉化爲中國插槽。
使用場景
適配器模式的使用場景部分,我們還是以jQuery
爲例子,這裏有一個比較典型的事例,就是jQuery
的ajax
請求。我們知道在jQuery
中使用ajax
進行網絡請求,我們應該如何使用?
$.ajax({
url: '/test',
type: 'POST',
dataType: 'json',
data: {
id: "123"
}
})
這是一個標準的ajax
請求方式對吧,那麼現在我們的應用覺得不再使用jQuery
進行網絡請求了,改用現在比較火的axios
進行網絡請求,那麼我們應該怎麼辦 ? 我們先來看一下axios
的標註請求方式。
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
});
這是axios
的標註網絡請求方式,大家想一下如果要替換爲axios
那麼應該怎麼做?通常的做法有兩種:
- 第一種做法就是全局替換,把所有的
$.ajax
替換爲axios
。不過這種方式,不用說大家可能也知道,坑比較多,很有可能出現各種各樣的問題。 - 第二種方法就是使用適配器模式,我們通過適配器來把所有的
$.ajax
轉化爲axios
的網絡請求。我們來看一下應該怎麼做。
先整理一下思路,我們希望把所有的$.ajax(options)
都變爲axios(options)
,那麼我們就需要對$.ajax(options)
添加一個適配器,通過適配器來把所有的請求轉到axios(options)
上,所以我們的代碼應該是這樣:
class Adapter {
specificAjax(options) {
axios({
method: options.type,
url: options.url,
data: options.data
});
}
};
$.ajax = function (options) {
const adapter = new Adapter();
adapter.specificAjax(options);
}
$.ajax({
url: '/test',
type: 'POST',
dataType: 'json',
data: {
id: "123"
}
})
這樣我們就可以通過適配器adapter
來把所有的$.ajax(options)
都變爲axios(options)
,並且我們不需要改變以前的任何代碼!
總結
OK
,進入我們的總結部分。我們應該在什麼情況下考慮適配器模式?當我們的舊方法不在能適應我們的需求的時候,我們需要對舊方法進行改變,這時我們就可以考慮使用適配器模式。使用適配器模式不會改變我們舊方法的調用代碼,並且可以最大程度的降低耦合度。 所以,如果大家遇到了這樣的問題,那麼需要首先考慮使用適配器模式。