自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

前端的設(shè)計(jì)模式系列-適配器模式

開(kāi)發(fā) 前端
大部分講設(shè)計(jì)模式的文章都是使用的 Java、C++ 這樣的以類(lèi)為基礎(chǔ)的靜態(tài)類(lèi)型語(yǔ)言,作為前端開(kāi)發(fā)者,js 這門(mén)基于原型的動(dòng)態(tài)語(yǔ)言,函數(shù)成為了一等公民,在實(shí)現(xiàn)一些設(shè)計(jì)模式上稍顯不同,甚至簡(jiǎn)單到不像使用了設(shè)計(jì)模式,有時(shí)候也會(huì)產(chǎn)生些困惑。

代碼也寫(xiě)了幾年了,設(shè)計(jì)模式處于看了忘,忘了看的狀態(tài),最近對(duì)設(shè)計(jì)模式有了點(diǎn)感覺(jué),索性就再學(xué)習(xí)總結(jié)下吧。

大部分講設(shè)計(jì)模式的文章都是使用的 Java、C++ 這樣的以類(lèi)為基礎(chǔ)的靜態(tài)類(lèi)型語(yǔ)言,作為前端開(kāi)發(fā)者,js 這門(mén)基于原型的動(dòng)態(tài)語(yǔ)言,函數(shù)成為了一等公民,在實(shí)現(xiàn)一些設(shè)計(jì)模式上稍顯不同,甚至簡(jiǎn)單到不像使用了設(shè)計(jì)模式,有時(shí)候也會(huì)產(chǎn)生些困惑。

下面按照「場(chǎng)景」-「設(shè)計(jì)模式定義」- 「代碼實(shí)現(xiàn)」- 「更多場(chǎng)景」-「總」的順序來(lái)總結(jié)一下,如有不當(dāng)之處,歡迎交流討論。

場(chǎng)景

當(dāng)我們使用第三方庫(kù)的時(shí)候,常常會(huì)遇到當(dāng)前接口和第三方接口不匹配的情況,比如使用一個(gè) Table 的組件,它要求我們返回的表格數(shù)據(jù)格式如下:

{
code: 0, // 業(yè)務(wù) code
msg: '', // 出錯(cuò)時(shí)候的提示
data: {
total: , // 總數(shù)量
list: [], // 表格列表
}
};

但后端返回的數(shù)據(jù)可能是這樣的:

{
code: 0, // 業(yè)務(wù) code
message: '', // 出錯(cuò)時(shí)候的提示
data: {
total: , // 總數(shù)量
records: [], // 表格列表
}
};

此時(shí)就可以通過(guò)適配器模式進(jìn)行轉(zhuǎn)換。

適配器模式

看一下 維基百科 給的定義:

★In software engineering, the adapter pattern is a software design pattern that allows the interface of an existing class to be used as another interface.[1] It is often used to make existing classes work with others without modifying their source code.”通過(guò)適配器模式可以讓當(dāng)前 class 不改變的情況下正常使用另一個(gè) class。

在以 class 為基礎(chǔ)的語(yǔ)言中有兩種實(shí)現(xiàn)方式,一種是通過(guò)組合的方式,適配器類(lèi)內(nèi)部包含原對(duì)象的實(shí)例。一種是通過(guò)類(lèi)繼承,適配器類(lèi)繼承原 class ??梢钥聪?UML 類(lèi)圖:

image-20220213124112500

左邊的 Adapter 內(nèi)部擁有 Adaptee的實(shí)例,右邊的 Adapter 類(lèi)直接繼承 Adaptee 類(lèi)。

適配器會(huì)將 Adaptee 的 specificOperation 方法進(jìn)行相應(yīng)的處理包裝為operation 方法供 client 使用。

看一個(gè)簡(jiǎn)單的例子,現(xiàn)實(shí)生活中iPhone 有兩種耳機(jī)插口,一種是 Lightning,一種是傳統(tǒng)的 3.5 毫米接口。如果是 lightning 插口的耳機(jī)想要插到傳統(tǒng)的 3.5 毫米接口的電腦上就需要適配器了。

class Lightning耳機(jī) {
public void 插入Lighting接口(){
System.out.println("插入到Lighting耳機(jī)接口成功");
}
}
class 傳統(tǒng)耳機(jī) {
public void 插入到傳統(tǒng)耳機(jī)孔(){
System.out.println("插入到傳統(tǒng)耳機(jī)孔成功");
}
}
class Lightning耳機(jī)到傳統(tǒng)耳機(jī)適配器 extends 傳統(tǒng)耳機(jī) {
public Lightning耳機(jī) Lightning耳機(jī);
public Lightning耳機(jī)到傳統(tǒng)耳機(jī)適配器(Lightning耳機(jī) 耳機(jī)) {
Lightning耳機(jī) = 耳機(jī);
}
public void 插入到傳統(tǒng)耳機(jī)孔(){
Lightning耳機(jī).插入Lighting接口();
}
}
class 電腦傳統(tǒng)耳機(jī)孔 {
public 傳統(tǒng)耳機(jī) 耳機(jī);
public 電腦傳統(tǒng)耳機(jī)孔(傳統(tǒng)耳機(jī) 傳統(tǒng)耳機(jī)) {
耳機(jī) = 傳統(tǒng)耳機(jī);
}
public void 插入耳機(jī)() {
耳機(jī).插入到傳統(tǒng)耳機(jī)孔();
}
}
public class Main {
public static void main(String[] args) {
傳統(tǒng)耳機(jī) 傳統(tǒng)耳機(jī) = new 傳統(tǒng)耳機(jī)();
電腦傳統(tǒng)耳機(jī)孔 電腦傳統(tǒng)耳機(jī)孔 = new 電腦傳統(tǒng)耳機(jī)孔(傳統(tǒng)耳機(jī));
電腦傳統(tǒng)耳機(jī)孔.插入耳機(jī)(); // 插入到傳統(tǒng)耳機(jī)孔成功


Lightning耳機(jī) Lightning耳機(jī) = new Lightning耳機(jī)();
電腦傳統(tǒng)耳機(jī)孔 電腦傳統(tǒng)耳機(jī)孔2 = new 電腦傳統(tǒng)耳機(jī)孔(new Lightning耳機(jī)到傳統(tǒng)耳機(jī)適配器(Lightning耳機(jī)));
電腦傳統(tǒng)耳機(jī)孔2.插入耳機(jī)(); // 插入到Lighting耳機(jī)接口成功
}
}

通過(guò)適配器我們成功將 Lightning 耳機(jī)插入到了電腦傳統(tǒng)耳機(jī)孔,讓我們?cè)儆胘s 改寫(xiě)一下。

const Lightning耳機(jī) = {
插入Lighting接口(){
console.log("插入到Lighting耳機(jī)接口成功");
}
}

const 傳統(tǒng)耳機(jī) = {
插入到傳統(tǒng)耳機(jī)孔(){
console.log("插入到傳統(tǒng)耳機(jī)孔成功");
}
}

const 電腦傳統(tǒng)耳機(jī)孔 = {
插入耳機(jī)(耳機(jī)) {
耳機(jī).插入到傳統(tǒng)耳機(jī)孔();
}
}

const Lightning耳機(jī)到傳統(tǒng)耳機(jī)適配器 = function(Lightning耳機(jī)) {
return {
插入到傳統(tǒng)耳機(jī)孔(){
Lightning耳機(jī).插入Lighting接口()
}
}
}

電腦傳統(tǒng)耳機(jī)孔.插入耳機(jī)(傳統(tǒng)耳機(jī)) // 插入到傳統(tǒng)耳機(jī)孔成功
電腦傳統(tǒng)耳機(jī)孔.插入耳機(jī)(Lightning耳機(jī)到傳統(tǒng)耳機(jī)適配器(Lightning耳機(jī))) // 插入到Lighting耳機(jī)接口成功

代碼實(shí)現(xiàn)

回到開(kāi)頭接口不匹配的問(wèn)題上,Table組件提供了一個(gè) responseProcessor的鉤子,我們只需要通過(guò)這個(gè)鉤子將接口返回的數(shù)據(jù)進(jìn)行包裝即可。

{
...
responseProcessor(res) {
return {
...res,
msg: res.message, // 出錯(cuò)時(shí)候的提示
data: {
...res.data
list: res?.data?.records || [], // 表格列表
}
};
},
...

}

更多場(chǎng)景

除了應(yīng)對(duì)數(shù)據(jù)格式不一致的問(wèn)題,通過(guò)適配器模式我們還可以為上層提供統(tǒng)一接口,來(lái)解決兼容性問(wèn)題。最典型的例子就是 jQuery ,可以看一下其中一段代碼:

// Create the request object
// (This is still attached to ajaxSettings for backward compatibility)
jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?

// Support: IE6-IE8
function() {

// XHR cannot access local files, always use ActiveX for that case
if ( this.isLocal ) {
return createActiveXHR();
}

// Support: IE 9-11
// IE seems to error on cross-domain PATCH requests when ActiveX XHR
// is used. In IE 9+ always use the native XHR.
// Note: this condition won't catch Edge as it doesn't define
// document.documentMode but it also doesn't support ActiveX so it won't
// reach this code.
if ( document.documentMode > 8 ) {
return createStandardXHR();
}

// Support: IE<9
// oldIE XHR does not support non-RFC2616 methods (#13240)
// See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx
// and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9
// Although this check for six methods instead of eight
// since IE also does not support "trace" and "connect"
return /^(get|post|head|put|delete|options)$/i.test( this.type ) &&
createStandardXHR() || createActiveXHR();
} :

// For all other browsers, use the standard XMLHttpRequest object
createStandardXHR;

易混設(shè)計(jì)模式

適配器模式和代理模式在代碼結(jié)構(gòu)上很像,代理模式也是對(duì)原對(duì)象進(jìn)行包裝處理。區(qū)別在于它們的意圖不同:

  • 適配器模式是為了解決兩個(gè)對(duì)象之間不匹配的問(wèn)題,而原對(duì)象又不適合直接修改,此時(shí)可以使用適配器模式進(jìn)行一層轉(zhuǎn)換。
  • 代理模式是為了增強(qiáng)原對(duì)象的功能,提供的接口不會(huì)改變。

適配器模式是一種比較簡(jiǎn)單的設(shè)計(jì)模式,在 js 中也會(huì)很自然的應(yīng)用,一般通過(guò)一個(gè)函數(shù)進(jìn)行轉(zhuǎn)換即可。


責(zé)任編輯:武曉燕 來(lái)源: windliang
相關(guān)推薦

2020-10-25 08:56:21

適配器模式

2013-11-26 16:39:21

Android設(shè)計(jì)模式

2021-02-18 08:39:28

設(shè)計(jì)模式場(chǎng)景

2012-05-16 17:22:11

Java設(shè)計(jì)模式

2022-12-12 09:20:59

適配器模式接口

2022-02-18 17:21:29

適配器模式客戶(hù)端

2024-02-22 12:13:49

適配器模式代碼

2024-07-31 10:41:16

C#設(shè)計(jì)模式

2012-04-12 09:33:02

JavaScript

2013-02-26 10:55:47

C#適配器設(shè)計(jì)模式

2012-08-02 10:46:34

JavaAdapter模式

2024-04-10 12:27:43

Python設(shè)計(jì)模式開(kāi)發(fā)

2022-05-29 22:55:00

適配器設(shè)計(jì)模式

2021-08-16 17:15:19

設(shè)計(jì)模式Android適配器模式

2021-02-16 08:16:09

適配器模式MybatisJava

2009-11-18 18:08:20

PHP適配器模式

2023-08-15 11:07:37

適配器模式TypeScript

2023-09-06 13:20:00

適配器模式兼容性

2022-02-11 10:22:48

模版模式語(yǔ)言

2022-02-15 22:45:00

前端設(shè)計(jì)模式
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)