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 })
这种情况,接口名称不同,入参方式不同,这要改到什么时候呢!
针对这种情况,就应该想到专门 抹平差异的 适配器模式。
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 }