“This is the 16th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”

The proxy pattern is a structural design pattern that allows you to provide substitutes for objects or placeholders for them. The proxy controls access to the original object and allows some processing before and after the request is submitted to the object.

describe

In real life, for example, mobile payments and credit cards act as proxies for bank accounts, which act as proxies for bundles of cash. They all implement the same interface and can be used to make payments. It gives consumers and businesses the satisfaction of not having to carry around large amounts of cash and receiving counterfeit money for change.

role

Problems with accessing objects directly, such as objects that are accessed on remote machines. In object-oriented systems, some object for some reason (such as the object creation overhead is very large, or some operations require safety control, or need to access) outside the process, will have direct access to caused a lot of trouble for the user or the system structure, during a visit to this object we can add an object to this access layer.

Suitable for the scene

  1. Lazy initialization (virtual proxy). Use proxy mode if you have a heavyweight service object that you use occasionally and keeping it running consumes system resources.
  2. Access control (secure proxy). If you only want specific clients to use service objects, which can be a very important part of the operating system, and clients are various started programs (including malicious ones), you can use proxy mode.
  3. Local execution of remote services (remote proxies). Applies when the service object is located on a remote server.
  4. Caching request results (caching proxy).

Implementation approach

  1. If there is no existing service interface, you need to create an interface to implement interchangeability between the proxy and the service object. Extracting an interface from a service class is not always feasible because you need to modify all clients of the service to use the interface. The alternative plan is to subclass the proxy as a service class so that the proxy can inherit all the interfaces of the service.
  2. Create a proxy class that must contain a member variable that stores a reference to the service. Typically, an agent is responsible for creating a service and managing its entire life cycle. In some special cases, the client passes the service to the broker through the constructor.
  3. Implement the proxy method as required. In most cases, the agent should delegate work to the service object after completing some tasks.
  4. Consider creating a new build method to determine whether a proxy or an actual service is available to the client. You can create a simple static method in the proxy class or a full factory method.
  5. Consider implementing lazy initialization for service objects.

Protection agency

Now In order to expand his business, Liu Bei plans to invite Zhuge Liang to be born, so we can use the code to describe and define an object between Liu Bei and Zhuge Liang. Liu Bei has a method of invitation, and Zhuge Liang has a method of receiving gifts. Normally, we can do as follows:

/ / liu bei
class Bei {
  constructor(user) {
    this.user = user;
  }
  invite(){
    this.user.reception('sandals')}}/ / bright
class Liang {
  // Receive a gift
  reception(gift){
    console.log('Liang received a gift:' + gift); // Ryo received the straw sandals and was very happy
  }
  reject(gift) {
    console.log('Refuse a gift:' + gift)
  }
}

const bei = new Bei(new Liang());
bei.invite()
// Ryo receives a gift: straw sandals
Copy the code

But actually Zhuge Liang was a big name, and not everyone could see him, so he needed an intermediary doorman to filter out people he didn’t like. The doorman is the agent

/ / liu bei
class Bei {
  constructor(user) {
    this.user = user;
  }
  invite(){
    this.user.reception('sandals')}}class Liang {
  // Receive a gift
  reception(gift){
    console.log('Liang received a gift:' + gift)
  }
  reject(gift) {
    console.log('Refuse a gift:' + gift)
  }
}

class Mentong{
  constructor(liang) {
    this.liang = liang;
  }
  // Instead of receiving gifts
  reception(gift){
    console.log('Doorman receives gift:' + gift)
    // At Zhuge Liang's request, only straw sandals were harvested
    if(gift === 'sandals') {
      // To Zhuge Liang
      this.liang.reception(gift)
    } else {
      this.liang.reject(gift)
    }
  }
}
const mentong = new Mentong(new Liang()); // Create a doorman to receive gifts for Zhuge Liang
const bei = new Bei(mentong); // Liu Bei gave the gift to the doorman first
bei.invite()
// The doorman receives a gift: straw sandals
// Ryo receives a gift: straw sandals
Copy the code

This is the protection agent, protection Zhuge Liang can only receive sandals, others to send gold and silver jewelry all do not;

Virtual agent

If Zhuge Liang’s request changed and he had to give him other gifts, Liu Bei was very worried. He had no other gifts, so he gave money to the doorman directly and asked the doorman to buy gifts for Zhuge Liang

class Mentong{
  constructor(liang) {
    this.liang = liang;
  }
  // Instead of receiving gifts
  reception(gift){
    const book = new Book(); / / to buy books
    this.liang.reception(book)
  }
}
Copy the code

Through the door boy Liu Bei sent a book, this is virtual agent

The proxy implements image preloading

Usually if we need to create an IMG tag and display an image. You can do this

// Create an ontology object
var myImage = (function(){
  // Create a label
  var imgNode = document.createElement('img');
  // Add to the page
  document.body.appendChild(imgNode);
  return {
    // Set the image SRC
    setSrc: function(src){
      / / change the SRCimgNode.src = src; }}}) (); myImage.setSrc('Picture address');
Copy the code

However, due to network or other reasons, the image will be blank before loading, so we can implement a preloading agent

// Create an ontology object
var myImage = (function(){
  // Create a label
  var imgNode = document.createElement('img');
  // Add to the page
  document.body.appendChild(imgNode);
  return {
    // Set the image SRC
    setSrc: function(src){
      / / change the SRCimgNode.src = src; }}}) ();// Create a proxy object
var proxyImage = (function(){
  // Create a new img tag
  var img = new Image();
  // img completes the loading event
  img.onload = function(){
    // Call myImage instead of SRC
    myImage.setSrc(this.src);
  }
  return {
    // The proxy sets the address
    setSrc: function(src){
      // Preloading loading
      myImage.setSrc('loading.gif');
      // Assign a normal image addressimg.src = src; }}}) (); proxyImage.setSrc('Picture address');

Copy the code

Loading is shown by the proxy before the image is loaded