js设计模式--结构型--适配器模式

  结构型: 适配器模式

  适配器模式:通过把一个类的接口变换成客户端所期待的另一种接口,通常解决不兼容问题。

  具体的业务实现场景,小明用 fetch 封装了一个 http 的方法库:

 1 export default class HttpUtils {
 2   // get方法
 3   static get(url) {
 4     return new Promise((resolve, reject) => {
 5       // 调用fetch
 6       fetch(url)
 7         .then((response) => response.json())
 8         .then((result) => {
 9           resolve(result);
10         })
11         .catch((error) => {
12           reject(error);
13         });
14     });
15   }
16   // post方法,data以object形式传入
17   static post(url, data) {
18     return new Promise((resolve, reject) => {
19       // 调用fetch
20       fetch(url, {
21         method: "POST",
22         headers: {
23           Accept: "application/json",
24           "Content-Type": "application/x-www-form-urlencoded",
25         },
26         // 将object类型的数据格式化为合法的body参数
27         body: this.changeData(data),
28       })
29         .then((response) => response.json())
30         .then((result) => {
31           resolve(result);
32         })
33         .catch((error) => {
34           reject(error);
35         });
36     });
37   }
38 
39   // body请求体的格式化方法
40   static changeData(obj) {
41     var prop,
42       str = "";
43     var i = 0;
44     for (prop in obj) {
45       if (!prop) {
46         return;
47       }
48       if (i == 0) {
49         str += prop + "=" + obj[prop];
50       } else {
51         str += "&" + prop + "=" + obj[prop];
52       }
53       i++;
54     }
55     return str;
56   }
57 }
58 // 定义目标url 地址
59 const url = "www.xxx";
60 // 定义 post 参数
61 const params = {};
62 // 发起 post 请求
63 const postResponse = (await HttpUtils.post(URL, params)) || {};
64 // 发起get请求
65 const getResponse = (await HttpUtils.get(URL)) || {};

  然后,老板看了 这个 HttpUtils 方法库,觉得很好用,让小明把公司的业务网络请求都迁移到 HttpUtils 上面,但是公司的网络请求库,是基于XMLHttpRequest的

大概就是下面这个样子:

 1 function Ajax(type, url, data, success, failed) {
 2   // 创建ajax对象
 3   var xhr = null;
 4   if (window.XMLHttpRequest) {
 5     xhr = new XMLHttpRequest();
 6   } else {
 7     xhr = new ActiveXObject("Microsoft.XMLHTTP");
 8   }
 9   // (此处省略一系列的业务逻辑细节)
10   var type = type.toUpperCase();
11   // 识别请求类型
12   if (type == "GET") {
13     if (data) {
14       xhr.open("GET", url + "?" + data, true); //如果有数据就拼接
15     }
16     // 发送get请求
17     xhr.send();
18   } else if (type == "POST") {
19     xhr.open("POST", url, true);
20     // 如果需要像 html 表单那样 POST 数据,使用 setRequestHeader() 来添加 http 头。
21     xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
22     // 发送post请求
23     xhr.send(data);
24   }
25   // 处理返回数据
26   xhr.onreadystatechange = function () {
27     if (xhr.readyState == 4) {
28       if (xhr.status == 200) {
29         success(xhr.responseText);
30       } else {
31         if (failed) {
32           failed(xhr.status);
33         }
34       }
35     }
36   };
37 }
38 // 调用方法
39 // 发送get请求
40 Ajax('get', url地址, post入参, function(data){
41     // 成功的回调逻辑
42 }, function(error){
43     // 失败的回调逻辑
44 })
View Code

  这种情况,接口名称不同,入参方式不同,这要改到什么时候呢!

  针对这种情况,就应该想到专门 抹平差异的 适配器模式。

 1 // ajax 适配器,入参和旧接口的保持一致
 2 async function AjaxAdapter(type, url, data, success, failed) {
 3   const type = type.toUpperCase();
 4   let result;
 5   try {
 6     // 实际的请求全部由新接口发起
 7     if (type === "GET") {
 8       result = (await HttpUtils.get(url)) || {};
 9     } else if (type === "POST") {
10       result = (await HttpUtils.post(url, data)) || {};
11     }
12     // 假设请求成功对应的状态码是1
13     result.statusCode === 1 && success
14       ? success(result)
15       : failed(result.statusCode);
16   } catch (error) {
17     // 捕捉网络错误
18     if (failed) {
19       failed(error.statusCode);
20     }
21   }
22 }
23 // 用适配器 适配旧的 ajax 方法,实现了新旧接口的无缝链接
24 async function Ajax(type, url, data, success, failed){
25     await AjaxAdapter(type, url, data, success, failed);
26 }
原文地址:https://www.cnblogs.com/Sabo-dudu/p/14653320.html