I Love ReactJS

JavaScript Common Design patterns (3) Agent pattern

Today we will learn the design pattern commonly used in JavaScript-- proxy pattern

In real life, an agent generally means that handles transactions on behalf of the authorized party . In law, it refers to the expression of intention of the agent, the authorized party, to act legally with a third party in his own name. A legal act committed as a result of authorization may have legal effect directly on the authorized party.

that is, when it is not convenient for the customer to access an object directly, a proxy object can be provided for the customer to access. After a series of processing to the request, the proxy object transfers the request to the ontology object.

definition

provides a substitute or placeholder for each object to control access to it. The stand-in object can process the request in advance and then decide whether to transfer it to the ontology object.

there are also many proxy modes, such as protection agents and virtual agents. Protection Agent is used to control access to target objects with different permissions; Virtual Agent refers to delaying the creation of expensive objects until they are really needed.

Application scenario

when we access an object directly, or when we are dissatisfied with our needs, we can consider using a stand-in object to control the access to that object.

Let's look at the virtual proxy mode with an example of image preloading:

before use

first use a loaded picture to occupy space, then load the picture asynchronously, and then fill it into the img node when the image is loaded.

Native function

const rawImage = (() => {
  // create an image node
  const imgNode = document.createElement("img");
  // add a picture node to the page
  document.body.appendChild(imgNode);
  // return an object and provide an interface
  return {
    // there is a method in the object to accept the image url.
    setSrc: (src) => {
      // point the src of the picture node to the local file
      imgNode.src = "./loading.gif";
      // create a new picture
      const img = new Image();
      // point the src of the picture to the incoming src
      img.src = src;
      // when the image is loaded, change the src of the image node to the src of img
      img.onload = () => {
        imgNode.src = this.src;
      };
    },
  };
})();
rawImage.setSrc("http://xxx.gif");

violates single responsibility principle in our design principle . Everything is done in the native function, so we need to decouple.

after use

Native functions only provide the functions of creating picture nodes and setting picture links

const rawImage = (() => {
  const imgNode = document.createElement("img");
  document.body.appendChild(imgNode);
  return {
    setSrc: (src) => {
      imgNode.src = src;
    },
  };
})();

set up a proxy function, do some operations through the proxy, load the picture, set the load diagram

const proxyImage = (() => {
  // create a new picture
  const img = new Image();
  // when the image is loaded, call the modified src API of the native function
  img.onload = () => {
    rawImage.setSrc(this.src);
  };
  
  return {
    // set to load pictures
    setSrc: (src) => {
      rawImage.setSrc("./loading.gif");
      img.src = src;
    },
  };
})();
proxyImage.setSrc("http://xxx.gif");

the advantage of writing this is that the proxy function is used to control the user's access to the native function, and some additional operations can be done in the proxy function.

Exit mobile version