“This is the 11th day of my participation in the August More Text Challenge. For details, see: August More Text Challenge.”
preface
At the top end of the interview, often encounter some questions about design patterns, each time the answer is not ideal. Coincides with the more challenging activities in August, I am prepared to spend a month to get a good understanding of design patterns, so as to increase my confidence for the interview.
define
Code pattern: Provides a substitute or placeholder for an object in order to control access to it.
The key
The key to the proxy pattern is to provide a surrogate object to control access to an object when it is inconvenient or unsatisfying for the program to access it directly. The program actually accesses the surrogate object. After the surrogate object does some processing on the request, it passes the request to the ontology object.
Proxy patterns in JavaScript
There are many variations of the proxy pattern, not all of which are suitable for use in JavaScript. This article will focus on two of the most common proxies used in JavaScript development: virtual proxies and cached proxies.
Virtual agent
Virtual proxies delay the creation of expensive objects until they are really needed. Here is an example of implementing the image preloading function to introduce the virtual agent.
Image preloading is a common technique. If you directly set the SRC attribute to an IMG tag node, the image will be empty for a period of time due to the size of the image or poor network. It is common to use a loading image as a placeholder, then load the image asynchronously, and then fill it into the IMG node when the image is loaded. This is a good scenario for using a virtual proxy.
Start by creating a MyImage class that will generate an IMG node and insert it into the body.
class MyImage { constructor() { this.img = document.createElement('img'); document.body.appendChild(this.img); } setSrc(src) { this.img.src = src; }}Copy the code
Const myImage = new myImage () generates an IMG node and inserts it into the body. Then set the SRC attribute to the img node by executing myimage.setsrc (‘ XXX ‘), and you can see that the page will be blank for a while before the image is loaded.
To solve this problem. Write a proxy class ProxyImage. With this proxy class, a loading image placeholder will appear on the page before the image is loaded, prompting the user that the image is loading.
class ProxyImage {
constructor() {
this.myImage = new MyImage();
this.image = new Image();
this.image.onload = function () {
this.myImage.setSrc(this.image.src);
}
}
setSrc(src) {
this.myImage.setSrc('./loading.gif');
this.image.src = src;
}
}
const proxyImage = new ProxyImage();
proxyImage.setSrc(xxxx);
Copy the code
The ProxyImage class controls access to the object instantiated by MyImage and adds some additional operations to the process. For example, before the actual image is loaded, Set img node’s SRC to a local loading image.
Proxyimage.setsrc (XXXX); this.myimage.setsrc (‘./ load.gif ‘); The SRC property of the Image object created by new Image() is assigned to the actual Image address XXXX. After the image object is loaded successfully, the image address XXXX is re-assigned to the SRC attribute of the img node through this.myimage.setsrc (this.image.src).
In this way, before the actual image to be displayed is loaded successfully, the IMG node generated by MyImage class instantiation will always display loading placeholder map, realizing the function of image preloading.
The meaning of agency
If you can achieve the function of image preloading without virtual agent, of course, the following to achieve:
class MyImage { constructor() { this.img = document.createElement('img'); document.body.appendChild(this.img); this.image = new Image(); image.onload = function () { this.img.src = this.image.src; }; } setSrc(src) { this.img.src = './loading.gif'; this.image.src = src; }}Copy the code
At first glance, the amount of code is less, the code is simpler. But this violates the design pattern’s principle of single responsibility. In addition to generating the IMG node and setting the SRC, the MyImage class is also responsible for preloading the image.
If an image is so small that it does not need to be preloaded at all, there is also the problem of the placeholder flashing by using preloading. So what do we do? Do you want to rewrite the MyImage class? That would violate the open-close principle
In fact, the MyImage class only needs to set SRC to the img node. Preloading the image is just the icing on the cake. The agent is responsible for preloading the image. Once the preloading is complete, it is handed back to the MyImage class to set the SRC for the img node.
We’re not changing or adding functionality to MyImage, we’re just adding functionality to the MyImage class through the proxy. This is in line with the open – closed principle.
The img node’s SRC and image preload functions are separated into two classes that can change without affecting each other. And even if one day we don’t need preloading anymore, we just need to request the ontology instead of requesting the proxy object.