Introduction
Agent, as the name suggests, is to help others do things. GoF defines the agency model as follows:
Proxy mode (Proxy) provides a proxy for other objects to control access to this object.
The proxy pattern enables proxy objects to control references to specific objects. A proxy can be almost any object: a file, a resource, an object in memory, or something difficult to copy.
Text
Let’s give a simple example. If Dudu wants to send roses to the yogurt girl, but he doesn’t know her contact information or is embarrassed, and wants to entrust an uncle to send these roses, then the uncle will be an agent (actually it’s quite good) , you can deduct a few flowers for your daughter-in-law), then how should we do it?
// This is dudu
var dudu = function (girl) {
This.girl = girl;
This.sendGift = function (gift) {
alert("Hi " girl.name ", dudu gives you a gift: " gift);
}
};
//Uncle is an agent
var proxyTom = function (girl) {
This.girl = girl;
This.sendGift = function (gift) {
(new dudu(girl)).sendGift(gift); // Send flowers to dudu
}
};
The calling method is very simple:
Practical combat
Through the above code, I believe everyone is very clear about the proxy mode. Let’s practice it: We have a simple playlist and need to display the video music below the link when clicking on a single link (or selecting all). Introduction and play button. When you click the play button, the video will be played. The list structure is as follows:
Select all/inverse selection
Let’s analyze it first. First, we must not only monitor the click event of the a connection, but also monitor the click event of “select all/inverse selection”. Then request the server to query the video information, assemble the HTML information and display it at the last position of the li element. on, the effect is as follows:
Then monitor the click event of the play connection, and start playing after clicking. The effect is as follows:
Okay, let’s start, without jQuery, let’s customize a selector:
sql = sql.replace('%ID%', ids.join('","'));
sql = encodeURIComponent(sql);
url = sql '&' format '&' handler;
script.src = url;
document.body.appendChild(script);
}
};
The proxy objects are as follows:
// Add to the queue dd to the queue
This.ids.push(id);
this.callback = callback;
This.context = context;
// Set timeout
If (!this.timeout) {
This.timeout = setTimeout(function () {
proxy.flush();
}, this.delay);
}
},
// Trigger the request and call http.makeRequest
using proxy responsibility
flush: function () {
// proxy.handler is the callback
when requesting yahoo
http.makeRequest(this.ids, 'proxy.handler');
// After requesting data, execute the proxy.handler method (there is another set callback)
//Clear timeout and queue
This.timeout = null;
This.ids = [];
},
Handler: function (data) {
var i, max;
// Callback call for a single video
If (parseInt(data.query.count, 10) === 1) {
proxy.callback.call(proxy.context, data.query.results.Video);
return;
}
// Callback calls for multiple videos
for (i = 0, max = data.query.results.Video.length; i < max; i = 1) {
proxy.callback.call(proxy.context, data.query.results.Video[i]);
}
}
};
The video processing module mainly has three sub-functions: obtaining information, displaying information, and playing videos:
if (data.query) {
data = data.query.results.Video;
}
id = data.id;
html = '';
html = '
' data.copyrightYear ', ' data.label '
';Album: ' data.Album.Release.title ', ' data.Album.Release.releaseYear '
';
}
html = '
if (!info) {
proxy.makeRequest(id, videos.updateList, videos); //执行代理职责,并传入videos.updateList回调函数
return;
}
if (info.style.display === "none") {
info.style.display = '';
} else {
info.style.display = 'none';
}
}
};
Now we can process the code for click events. Since there are many A connections, if each connection binds an event, there will obviously be performance problems, so we bind the event to the
e = e || window.event;
src = e.target || e.srcElement;
// If it is not connected, the process will not continue
If (src.nodeName.toUpperCase() !== "A") {
return;
}
//Stop bubbling
If (typeof e.preventDefault === "function") {
e.preventDefault();
}
e.returnValue = false;
id = src.href.split('--')[1];
//If you click on the link play of the video information area that has been produced, start playing
// Then return does not continue
If (src.className === "play") {
src.parentNode.innerHTML = videos.getPlayer(id);
return;
}
src.parentNode.id = "v" id;
Videos.getInfo(id); // This is the processing code to display video information when clicked for the first time
};
The codes for selecting all and inverting selection are similar, so we won’t explain them:
var hrefs, i, max, id;
hrefs = $('vids').getElementsByTagName('a');
for (i = 0, max = hrefs.length; i < max; i = 1) {
//Ignore play connection
If (hrefs[i].className === "play") {
continue;
}
//Ignore unselected items
If (!hrefs[i].parentNode.firstChild.checked) {
continue;
}
id = hrefs[i].href.split('--')[1];
hrefs[i].parentNode.id = "v" id;
videos.getInfo(id);
}
};
Summary
The proxy mode is generally suitable for the following situations:
1. Remote proxy is to provide local representation for an object in different address spaces. This can hide the fact that an object exists in different address spaces, just like the proxy class in web service.
2. Virtual proxy, create expensive objects as needed, and use it to store real objects that take a long time to instantiate. For example, when the browser renders, the problem will be displayed first, and the picture can be displayed slowly (that is, through the virtual proxy Instead of the real image, the virtual agent saves the path and size of the real image
.
3. Security proxy is used to control the permissions when accessing real objects. It is generally used for objects that should have different access permissions.
4. Intelligent guidance, only when the real object is called, the agent handles other things. For example, in garbage collection in C#, when an object is used, there will be a reference count. If the object is no longer referenced, the GC can recycle it.
Reference: "Dahua Design Pattern"