Proxy mode of javascript

 Previous << Factory Pattern of JavaScript Design Pattern >>

The proxy pattern is to provide a surrogate or placeholder for an object in order to control access to it
The usefulness of the proxy mode (personal understanding):
In order to ensure the single responsibility (relative independence) of the current object,
It is necessary to create another object to process some logic before calling the current object to improve the efficiency of the code, state judgment, etc. 
The most commonly used proxy modes are virtual proxy and caching proxy

In real life, you can find many scenarios where the proxy mode is used. Celebrities have agents as agents. If you invite a star to perform, you must first communicate with his agent to discuss the corresponding details and remuneration. to the stars.
Demand: The company (Company) finds a star (start) to hold a concert through an agent (agent)

//演唱会
var Concert = function(){}
//公司
var Company = {
    askforconcert: function(target){
       var concert = new Concert();
       target.openconcert(concert )
    }

}
//明星
var star = {
    openconcert: function(concert){
         console.log("明星同意开一场演唱会")
    }
}
//经纪人代理
var agent = {
    openconcert: function(concert){
        star.openconcert(concert)
    }
}
//执行
Company.askforconcert(agent);  //=>明星同意开一场演唱会
/*这样 company直接把请求发给agent,agent再转给star,这样就完成了一个简单的代理模式
(compan=>agent=>star)*/
//经济人可以帮助 明星过滤掉一些请求,比如 钱不够多或者场地不够好,这种请求可以直接在经纪人出被过滤拒绝掉。
//这种代理就叫做保护代理。 
//由经纪人Agent来控制对明星star的访问。

1. Virtual agent

- If A sends flowers to C through B, we can pass a new flower to agent B at the time of A, and then B decides when or whether to transfer the final target C again. The new Flower operation can be handed over to B. When B decides that it can send flowers to C, B will do the new Flower operation. This mode is called a virtual agent. Virtual proxies delay the creation of some expensive objects until they are really needed

var Flower = function(){
    this.price = 150
}
var a = {
  sendflower: function(target){
        var flower = new Flower()
        target.receiveFlower(flower )
    }
}
var b = {
    receiveFlower: function(flower){
        if(flower.price < 100){
          console.log("太便宜了,女神表示一脸嫌弃")
          return false
        }else{
            c.receiveFlower(flower)
        }
    },
    
        
}
var c = {
    receiveFlower: function(){
        console.log("接受了鲜花")
    }
}

1. Realize image preloading

//不使用代理
var  preLoadImage = (function(){
    var imgNode = document.createElement('img');
    document.body.append(imgNode)
    var img = new Image();
    img.onload = function(){
      imgNode.src = img.src
    }
    return {
        setSrc: function(src){
            imgNode.src = "loading.gif";
            img.src = src;
        }
    }
})()  
//使用代理模式的实现方式
var image = (function(){
    var imgNode = document.createElement('img');
    document.body.append(imgNode);
    return {
        setSrc: function(src){
            imgNode.src = src;
        }
    }
})()
//代理
var proxyImage = (function(){
    var img = new Image();
    img.onload = function(){
// 图片加载完成,正式加载图片
        image.setSrc = img.src;
    }
    return {
        setSrc: function(src){
            image.setSrc = "loading.gif";
            img.src = src;
        }
    }
})

Single Responsibility Principle
Single responsibility means that there should be only one reason for a class to change. If an object assumes multiple principles, it means that the object will become huge, and there may be multiple reasons for its change. Object-oriented design encourages the separation of behavior into fine-grained objects. If an object has too many responsibilities, it is equivalent to coupling these values ​​together, which can lead to fragile and low-cohesion designs. When changes occur, designs can be broken unexpectedly. (93 pages in the book)

The preLoadImage method is responsible for adding img tags and preloading two functions. The code is coupled together. When I modify and add tags, it may affect another part of the function.

After refactoring with the proxy method, the image method is only responsible for creating labels, setting src, and handing over the preloading function to proxyImage, decoupling the code, and the two functions do not interfere with each other.

2. Virtual proxy merges http requests

var syncFile = function(id){
    $.ajax({
        data: {
            id: id
        }
    })...
}
//绑定事件
for(var i = 0;i<fileObjArr.length;i++){
    fileObjArr[i].onclick = function(){
        if(this.checked === true){
            syncFile(this.id)
        }
    }
}

There is a very serious problem here. Each point will send an ajax request. In terms of performance, this is a lot of overhead.

  • Requirement: The file is synchronously worn, and the selected file will be uploaded to the server. As a solution, we can use a proxy function to collect requests within a period of time, cache the requested parameters, and negotiate with the back-end personnel to select the id Passed to the background as an array to save.

var syncFile = function(ids){
    $.ajax({
        data: {
            id: ids
        }
    })...
}

var proxyFile = (function(){
    var cache = [],
        timer = null;

    return function(id){
        cache.push(id);
        if(timer){
            return
        }
        timer = setTimeout(function(){
            syncFile(cache.join(","))
            clearTimeout(timer);
            timer = null;
            cache = [];
        },2000)
    }
})()
//绑定事件
for(var i = 0;i<fileObjArr.length;i++){
    fileObjArr[i].onclick = function(){
        if(this.checked === true){
            proxyFile(id)
        }
    }
}

In this way, if there is a selection operation, the request will not be triggered frequently.

2. Cache proxy

The cache proxy can provide temporary storage for some expensive operation results. In the next operation, if the parameters passed in are the same as before,
The result of the previous operation can be returned.
  Example: Create caching proxies for multiplication, addition, etc.
// 计算乘积
var mult = function(){
    var a = 1;
    for( var i = 0, l = arguments.length; i < l; i++){
        a = a * arguments[i];
    }
    return a;
};
// 计算加和
var plus = function () {
  var a = 0;
    for( var i = 0, l = arguments.length; i < l; i++ ){
        a += arguments[i];
    }
    return a;
};
// 创建缓存代理的工厂
var createProxyFactory = function( fn ){
    var cache = {}; // 缓存 - 存放参数和计算后的值
    return function(){
        var args = Array.prototype.join.call(arguments, "-");
        if( args in cache ){ // 判断出入的参数是否被计算过
            console.log( "使用缓存代理" );
            return cache[args];
        }
        return cache[args] = fn.apply( this, arguments );
    }
};
// 创建代理
var proxyMult = createProxyFactory( mult ),
    proxyPlus = createProxyFactory( plus );

console.log( proxyMult( 1, 2, 3, 4 ) ); // 输出: 24
console.log( proxyMult( 1, 2, 3, 4 ) ); // 输出: 缓存代理 24
console.log( proxyPlus( 1, 2, 3, 4 ) ); // 输出: 10
console.log( proxyPlus( 1, 2, 3, 4 ) ); // 输出: 缓存代理 10

In reality

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325444783&siteId=291194637