introduce
The proxy mode is to add a function between the actual functions, so that we can indirectly access the used functions. So why bother putting a function in the middle? We can do two examples.
🌰 1: Xiao Ming pursues a girl
Methods a
- Give her flowers, you’ll get a 100% rejection.
Way 2
- Send flowers through a middleman whom xiao Ming and the girl both know, because the middleman knows the girl, the success rate is 30%.
Methods three
- She knew that girls would not refuse others when they were happy, so Xiao Ming put flowers in the middleman temporarily. The middleman decided when to send flowers by monitoring girls’ mood, with a success rate of 90%.
🌰 2: image preloading
In normal development, we may encounter pictures too large or network problems caused by the slow loading of pictures, so we can use proxy mode to achieve the pre-loading of pictures.
let myImage = function () {
let imgNode = document.createElement('img')
document.body.appendChild(imgNode);
return {
setSrc: function (src) {
imgNode.src = src
}
}
}()
let proxyImage = function () {
let img = new Image;
img.onload = function () {
myImage.setSrc(this.src)
}
return {
setSrc: function (src) {
myImage.setSrc('Local picture');
img.src = src
}
}
}()
proxyImage.setSrc("https://imgs.aixifan.com/nqiFgWPe8D-yuUNf2-YjaUfy-Mza6bm-QRF7Bj.png")
Copy the code
In this example we accessed myImage indirectly via proxyImage. ProxyImage controls the customer’s access to myImage and adds some additional actions, such as loading a local loading image before the actual image is loaded.
Meaning of agency
To illustrate the meaning of agency, we introduce a principle of object-oriented design — the single responsibility principle.
Single responsibility means that there should be only one cause for a class to change. If an object takes on more than one responsibility, it means that the object becomes large and can change for more than one reason. Object-oriented design encourages the distribution of behavior among fine-grained objects, and if an object takes on too many responsibilities, that responsibility is coupled together, which leads to fragile and low-cohesion designs. When changes occur, the design can be broken.
In most cases in object-oriented programming, if you violate any other principle, you must violate the open-closed principle. If we only get small images from the Internet, or if our Internet speed is fast enough to ignore the size limitation after 5 years, we can remove the proxyImage method and just use myImage. This is what the agent does. The agent preloads the image, and when it’s done, passes the request back to the ontology myImage.
Consistency of proxy and ontology interfaces
It says that one day we don’t need proxies anymore and can request ontologies directly. The key point is that both the proxy object and ontology provide setSrc methods externally. In the eyes of customers, the proxy and local are consistent, and the process of proxy taking over requests is transparent to users, who are not aware of the difference between proxy and ontology, which has two advantages:
- The user can safely request the broker, who only cares about getting the desired result
- Anywhere an ontology is used it can be replaced with a proxy
Proxy mode 1: Virtual proxy
Merging HTTP requests
There is a function description that when the check box is clicked, the file corresponding to the check box is uploaded to the server, so that when the customer clicks frequently, a large number of requests will be sent at the same time. If the demand for real time is not very high, we can create a request pool, after a fixed time to send the pool function.
<body>
<input type="checkbox" id="1"></input>1
<input type="checkbox" id="2"></input>2
<input type="checkbox" id="3"></input>3
<input type="checkbox" id="4"></input>4
<input type="checkbox" id="5"></input>5
<input type="checkbox" id="6"></input>6
<input type="checkbox" id="Seven"></input>7
<input type="checkbox" id="8"></input>8
<input type="checkbox" id="9"></input>9
</body>
<script type="text/javascript">
var proxySynchronousFile = (function () {
var cache = [], // Save the ids to be synchronized over a period of time
timer; / / timer
return function (id) {
cache.push(id);
if (timer) { // Ensure that the started timer is not overwritten
return;
}
timer = setTimeout(function () {
synchronousFile(cache.join(', ')); // Send the set of ids to be synchronized to the ontology after 2 seconds
clearTimeout(timer); // Empty the timer
timer = null;
cache.length = 0; // Clear the ID collection
}, 2000);
}
})();
var checkbox = document.getElementsByTagName('input');
// Next, bind these checkboxes to click events and synchronize files to another server at the same time:
for (var i = 0, c; c = checkbox[i++];) {
c.onclick = function () {
if (this.checked === true) {
proxySynchronousFile(this.id); }}};</script>
Copy the code
Proxy mode 2: Cache proxy
Calculation of the product
The cache proxy can provide temporary storage for some expensive operation results, and can return the stored results directly on the next operation if the parameters passed in are the same as before.
Create a function to evaluate the product:
var mult = function () {
console.log('Let's compute the product.');
var a = 1;
for (var i = 0, l = arguments.length; i < l; i++) {
a = a * arguments[i];
}
return a;
};
mult(2.3); // Output: 6
mult(2.3.4); // Output: 24
Copy the code
Now add the caching proxy function:
var proxyMult = (function () { var cache = {}; return function () { var args = Array.prototype.join.call(arguments, ','); if (args in cache) { return cache[args]; } return cache[args] = mult.apply(this, arguments); }}) (); proxyMult(1, 2, 3, 4); // Output: 24 proxyMult(1, 2, 3, 4); // Output: 24Copy the code
By adding a caching proxy, the mult function can focus on its own responsibility of calculating the product, and the caching function is performed by the proxy.
Create cache proxies dynamically with higher-order functions
Caching proxies can be created for various computation methods by passing in higher-order functions in a more flexible manner.
/**************** computes the product *****************/
var mult = function () {
var a = 1;
for (var i = 0, l = arguments.length; i < l; i++) {
a = a * arguments[i];
}
return a;
};
/**************** calculates plus and *****************/
var plus = function () {
var a = 0;
for (var i = 0, l = arguments.length; i < l; i++) {
a = a + arguments[i];
}
return a;
};
/**************** Create a factory for caching proxies *****************/
var createProxyFactory = function (fn) {
var cache = {};
return function () {
var args = Array.prototype.join.call(arguments.', ');
if (args in cache) {
return cache[args];
}
return cache[args] = fn.apply(this.arguments); }};var proxyMult = createProxyFactory(mult),
proxyPlus = createProxyFactory(plus);
alert(proxyMult(1.2.3.4)); // Output: 24
alert(proxyMult(1.2.3.4)); // Output: 24
alert(proxyPlus(1.2.3.4)); // Output: 10
alert(proxyPlus(1.2.3.4)); // Output: 10
Copy the code
conclusion
Proxy patterns The most commonly used in JavaScript are virtual proxies and caching proxies, and while the proxy pattern is useful, you don’t need to guess when you’re writing a business, only when you find it inconvenient to access an object directly.
reference
JavaScript design patterns and development practices