This is the first day of my participation in the More text Challenge. For details, see more text Challenge

I. What is the agency model

The proxy pattern provides a substitute or placeholder for an object in order to control access to it.

The key to the proxy pattern is to provide a surrogate object to control access to an object when it is inconvenient for the client to access it directly or when the client does not need it. The client is actually accessing the surrogate object.

Two, simulation scenario

Xiao Ming sent flowers to Xiao Bai

1.1 Traditional Practices

Traditionally, Xiao Ming sends the flowers directly to Xiao Bai, who receives them with the following code:

const Flower = function () {
	return 'rose 🌹'
}

const xiaoming = {
	sendFlower: target= > {
		const flower = new Flower()
		target.receiveFlower(flower)
	}
}

const xiaobai = {
	receiveFlower: flower= > {
		console.log('Received flowers', flower)
	}
}

xiaoming.sendFlower(xiaobai)
Copy the code

1.2 Agent Mode

However, xiao Ming does not know xiao Bai, he wants to help him through the small generation, to find out the situation of xiao Bai, in a good mood to send flowers, so that the success rate is higher. The code is as follows:

const Flower = function () {
	return 'rose 🌹'
}

const xiaoming = {
	sendFlower: target= > {
		const flower = new Flower()
		target.receiveFlower(flower)
	}
}

const xiaodai = {
	receiveFlower: flower= > {
		xiaobai.listenGoodMood().then(() = > {
			xiaobai.receiveFlower(flower)
		})
	}
}

const xiaobai = {
	receiveFlower: flower= > {
		console.log('Received flowers', flower)
	},
	listenGoodMood: fn= > {
		return new Promise((reslove, reject) = > {
			// After 10 seconds, the mood gets better
			reslove()
		})
	}
}

xiaoming.sendFlower(xiaodai)
Copy the code

Above, xiaoming through the small generation, listening to the change in the mood of the small white, choose to send flowers to the small white in a good mood. Not only that, small generations can also do the following:

  1. Helping White filter out requests for flowers is called a protection agent;
  2. Help Xiaoming, in a good mood, and then perform the operation of buying flowers, this is called virtual agent. Virtual proxies defer the creation of expensive objects until they are really needed.

Iii. Actual scenario

1. Image preloading

It is a common technique to preload images. If you directly set the SRC attribute to the img tag node, the position of the image will often be blank for a period of time due to the large image or poor network.

1.1 Traditional Practices

const myImage = (() = > {
	const imgNode = document.createElement('img')
	document.body.appendChild(imgNode)

	return {
		setSrc: src= > {
			imgNode.src = src
		}
	}
})()

myImage.setSrc('https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fa98e67c4708449eb6894c7133d93774~tplv-k3u1fbpfcp-watermark.image')

Copy the code

When you set the network speed to 5KB /s using the developer tool, you will notice that the image position is blank for a long time.

1.2 Virtual Proxy

The following is to optimize this function with virtual agent, and give the operation of loading the image to the agent function. When the image is loaded, a loading diagram is used to occupy the space, and when the image is loaded successfully, it is filled into the IMG node.

The code is as follows:

const myImage = (() = > {
	const imgNode = document.createElement('img')
	document.body.appendChild(imgNode)

	return {
		setSrc: src= > {
			imgNode.src = src
		}
	}
})()

const loadingSrc = '.. /.. /.. /.. /img/loading.gif'
const imgSrc = 'https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fa98e67c4708449eb6894c7133d93774~tplv-k3u1fbpfcp-watermark.image'

const proxyImage = (function () {
	const img = new Image()
	img.onload = () = > {
		myImage.setSrc(img.src)
	}

	return {
		setSrc: src= > {
			myImage.setSrc(loadingSrc)
			img.src = src
		}
	}
})()

proxyImage.setSrc(imgSrc)
Copy the code

The above code has the following advantages:

  1. ProxyImage controls access to MyImage, and loading diagram is used to occupy space before MyImage is successfully loaded;

  2. Following the single responsibility principle, MyImage, which sets SRC for the img node, and proxyImage, which preloads images, have only one responsibility;

  3. Following the open-close principle, img nodes are isolated from each other by setting SRC and preloading images. Each can change without affecting the other.

2. Merge HTTP requests

Suppose we want to implement a file synchronization function, through the check box, when the check box is selected, the corresponding ID of the check box to the server, tell the server to synchronize the id of the file.

If you think about it, if you request an interface for every check box you select, let’s say 10 check boxes are selected in 1 second, then you have to send 10 requests.

2.1 Virtual Proxy

You can optimize this with a virtual proxy by adding a proxy that helps check the box to initiate requests for synchronizing files, collect requests within 1s, and then send the file ids together to the server after 1s.

The code is as follows:

<! DOCTYPEhtml>
<html>
<meta charset="utf-8" />
<head>
	<title></title>
</head>
<body>
  a <input type="checkbox" value="a" />
  b <input type="checkbox" value="b" />
  c <input type="checkbox" value="c" />
  d <input type="checkbox" value="d" />
	<script type="text/javascript" src="index.js">
	</script>
</body> 
</html>
Copy the code
const synchronousFile = cache= > {
  console.log('Start synchronizing files, id:'+ cache.join('/'))}const proxySynchronousFile = (() = > {
  const cache = []

  let timer

  return id= > {
    console.log(id)
    cache.push(id)

    if (timer) {
      return
    }

    timer = setTimeout(() = > {
      synchronousFile(cache)
      clearTimeout(timer)
      timer = null
      cache.length = 0
    }, 2000)}}) ()const checkbox = document.getElementsByTagName('input')

Array.from(checkbox).forEach(i= > {
  console.log(i)
  i.onclick = () = > {
    if (i.checked) {
      proxySynchronousFile(i.value)
    }
  }
})


Copy the code

Github source address

3. Ajax requests data asynchronously

When the list needs paging, the data on the same page theoretically only need to go to the background to pull once, you can cache the data that has been pulled down, and the cached data can be directly used when the next request

3.1 Cache Proxy

To implement the above function using a caching proxy, the code is as follows:

(async function () {
  function getArticle (currentPage, pageSize) {
    console.log('getArticle', currentPage, pageSize)
    // Simulate an Ajax request
    return new Promise((resolve, reject) = > {
      resolve({
        ok: true.data: {
          list: [].total: 10.params: {
            currentPage, 
            pageSize
          }
        }
      })
    })
  }
  
  const proxyGetArticle = (() = > {
    const caches = []
  
    return async (currentPage, pageSize) => {
  
      const cache = Array.prototype.join.call([currentPage, pageSize],', ')
  
      if (cache in caches) {
        return caches[cache]
      }
      const { data, ok } = await getArticle(currentPage, pageSize)
  
      if (ok) {
        caches[cache] = data
      }
  
      return caches[cache]
    }
  })()

  // Search the first page
  await proxyGetArticle(1.10)
  
  // Search the second page
  await proxyGetArticle(2.10)

  // Search the first page again
  await proxyGetArticle(1.10)
  
})()


Copy the code

With the caching proxy, when the first page of data is requested a second time, the data is pulled directly from the cache, without the need to request the data from the server again.

Four, summary

The above describes the practices of virtual proxy and caching proxy according to actual scenarios.

When we cannot access an object directly, find a proxy method to access the object for us. This is the proxy pattern.

Github source code can be used for practice.

Hope to be helpful to you, thank you for reading ~ don’t forget to point a like to encourage me oh, pen refill ❤️


· Past wonderful ·

Design Patterns – Who hasn’t seen a few singletons (1)

Design Mode – What is happy Planet, What is Strategic Mode (part 2)

Design Mode – This is the Agent mode (3)

Design Patterns — Simple observer Patterns (part 4)

Design Mode – No, no, no, no, no, no, no, no.