阅读 84

设计模式-适配器模式

适配器模式又称为包装器模式,将一个类的接口转化为用户需要的另外一个接口,主要是为了解决对象之间接口不兼容的问题,比如随着业务迭代升级出现了旧的接口与心的接口不兼容,这个时候不可能强制使用旧接口的用户去升级,而是在中间加一个适配器进行转换,让旧接口的使用者无感使用,保证了稳定性,在日常生活中适配器的案例随处可见,比如耳机插口不统一、充电接口不统一等,这个时候就需要一个适配器来解决问题

UML:

image-20211007135111668.png

接下看一下UML对应的代码实现:

class Target {     constructor(type) {         let result;         switch (type) {             case "adapter":                 result = new Adapter();                 break;             default:                 result = null;         }         return result;     }     Request() {             console.log('Target Request');     } } class Adaptee {     constructor() {         console.log("Adaptee created");     }     SpecificRequest() {         console.log("Adaptee request");     } } class Adapter extends Adaptee {     constructor() {         super();         console.log("Adapter created");     }     Request() {         return this.SpecificRequest();     } } function init_Adapter() {     var f = new Target("adapter");     f.Request(); } init_Adapter(); 复制代码

应用场景

开发中常用的axios,其支持node端和浏览器端,那么在不同端调用axios需要进行不同的处理,而这些对于使用者而言都是无感的,我们在使用的时候都是使用同一套API直接干就完事了,不会在意内部具体做了些什么,这个时候就需要使用适配器来抹平不同端的差异,让使用者用着开心

接下来可以模拟简单实现这个过程

使用axios请求一个接口:

axios({     url: "xxx",     method: "GET", })     .then((res) => {         console.log("success:", res);     })     .catch((err) => {         console.log("fail:", err);     }); 复制代码

接下来需要手动实现axios函数:

function axios(config) {     let adaptor = getDefaultAdaptor();     // 无论是node端 还是 浏览器端,在使用的时候都只是转入一个config配置对象,返回一个 Promise 对象     return adaptor(config); } 复制代码

上文说到因为axios可以在浏览器端和node端使用,getDefaultAdaptor函数就是起到适配器的作用,根据不同的环境分别创建不同的adaptor

/**  * 适配器  */ function getDefaultAdaptor() {     let adaptor;     if (typeof XMLHttpRequest !== "undefined") {         // 是浏览器环境         adaptor = xhr;     } else if (typeof process !== "undefined") {         // node 环境         adaptor = http;     }     return adaptor; } 复制代码

其中xhr和http为两个函数,用于创建具体的请求,至此适配器的使用已经完成,接下来就看看不同端是如何实现的接口请求

浏览器端:

/**  * 浏览器环境  */ function xhr(config) {     return new Promise((resolve, reject) => {         const req = new XMLHttpRequest();         req.open(config.method, config.url, true);         req.onreadystatechange = function () {             if (req.readyState === 4) {                 if (req.status >= 200 && req.status < 300) {                     resolve(req.responseText);                 } else {                     reject("请求失败");                 }             }         };         req.send();     }); } 复制代码

node端:

/**  * node 环境  */ function http(config) {     const url = require("url");     const http = require("http");     // 将需要的参数 解析出来     const { hostname, port, path } = url.parse(config.url);     return new Promise((resolve, reject) => {         const options = {             hostname,             port,             path,             method: config.method,         };         const req = http.request(options, function (response) {             let chunks = [];             response.on("data", (chunk) => {                 chunks.push(chunk);             });             response.on("end", () => {                 const res = Buffer.concat(chunks).toString();                 resolve(res);             });         });         // 监听请求异常         req.on("error", (err) => {             reject(err);         });         // 请求发送完毕         ren.end();     }); }


作者:Nordon
链接:https://juejin.cn/post/7016215674322157581

文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐