Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”
Adapter model is also known as a wrapper, converting the interface of one class to another interface to meet the needs of users, mainly in order to solve the problem of interface is incompatible between objects, such as iterative upgrade as business the old interface interface is not compatible with heart, this time can’t be forced to use old interface users to upgrade, but add an adapter in the middle, In daily life, adapter cases can be seen everywhere, such as the disunity of headphone jack and charging interface. At this time, an adapter is needed to solve the problem
UML:
Take a look at the corresponding UML code implementation:
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(a);console.log("Adapter created");
}
Request() {
return this.SpecificRequest(); }}function init_Adapter() {
var f = new Target("adapter");
f.Request();
}
init_Adapter();
Copy the code
Application scenarios
Axios supports node and browser, so calling axios on different ends requires different processing, which is insensitive to the user. We use the same SET of apis to do things directly, and we don’t care what is done inside. At this point, you need to use adapters to smooth out the differences between the different ends and make users happy
You can then simulate a simple implementation of this process
Request an interface using AXIos:
axios({
url: "xxx".method: "GET",
})
.then((res) = > {
console.log("success:", res);
})
.catch((err) = > {
console.log("fail:", err);
});
Copy the code
Next you need to implement the AXIos function manually:
function axios(config) {
let adaptor = getDefaultAdaptor();
// On both the Node and browser sides, it simply goes to a config object and returns a Promise object
return adaptor(config);
}
Copy the code
Since AXIos can be used on both the browser and node sides, the getDefaultAdaptor function acts as an adaptor, creating different adaptors for different environments
/** * adapter */
function getDefaultAdaptor() {
let adaptor;
if (typeofXMLHttpRequest ! = ="undefined") {
// is the browser environment
adaptor = xhr;
} else if (typeofprocess ! = ="undefined") {
/ / the node environment
adaptor = http;
}
return adaptor;
}
Copy the code
XHR and HTTP are two functions that create specific requests. Now that the use of the adapter is complete, let’s see how the interface requests are implemented on different ends
Browser side:
/** * Browser environment */
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("Request failed"); }}}; req.send(); }); }Copy the code
The node side:
/** * node environment */
function http(config) {
const url = require("url");
const http = require("http");
// Parse the required parameters
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);
});
});
// The listening request is abnormal
req.on("error".(err) = > {
reject(err);
});
// The request is sent
ren.end();
});
}
Copy the code