Design pattern -- agent pattern

Xiao Guo is in Shenzhen 2021-09-15 06:31:30
design pattern agent pattern


1. Definition

The proxy pattern is to provide a surrogate or placeholder for an object , In order to control access to it .

The key to the agency model is , When the customer is inconvenient to directly access an object or does not meet the needs , Provide a surrogate object to control access to this object , The client is actually visiting a surrogate . After the stand in object does some processing to the request , And then pass the request to the ontology object .

2. Example

Xiao Hong gives Xiao Gang a gift

  • Without proxy mode
var Gift = function(){};
var xiaohong = {
sendGift: function(target) {
var gift = new Gift();
target.receiveGift(gift);
}
}
var xiaogang = {
receiveGift: function(gift) {
console.log(' Receive a gift ' + gift)
}
}
xiaohong.sendGift(xiaogang);
 Copy code 
  • Using the proxy pattern ( Xiao Hong sends Xiao Gang a gift through Xiao Ming )
var Gift = function(){};
var xiaohong = {
sendGift: function(target) {
var gift = new Gift();
target.receiveGift(gift);
}
}
var xiaoming = {
receiveGift: function(gift) {
xiaogang.receiveGift(gift)
}
}
var xiaogang = {
receiveGift: function(gift) {
console.log(' Receive a gift ' + gift)
}
}
xiaohong.sendGift(xiaogang);
 Copy code 

This is a simple proxy pattern . There seems to be no essential difference between the two , Introducing a proxy object just seems to complicate things . The proxy model here is really useless , Simply pass the request to the ontology .

Change the background of the above example : Xiao Gang accepted the gift and came with the change of mood

var Gift = function(){};
var xiaohong = {
sendGift: function(target) {
var gift = new Gift();
target.receiveGift(gift);
}
}
var xiaoming = {
receiveGift: function(gift) {
xiaogang.listenGoodMood(function(){ // Monitor Xiaogang's good mood 
xiaogang.receiveGift(gift)
})
}
}
var xiaogang = {
receiveGift: function(gift) {
console.log(' Receive a gift ' + gift)
},
listenGoodMood: function(fn) {
setTimeout(function(){ // hypothesis 10 Seconds later A I feel better 
fn()
}, 10000)
}
}
xiaohong.sendGift(xiaogang);
 Copy code 

3. Protect agents and virtual agents

3.1 Protection agency

agent “ Xiao Ming ” Can help “ Xiaogang ” Filter out some requests , For example, those who give gifts are too old , This request can be made directly in the agent “ Xiao Ming ” Was rejected . This agent is called “ Protection agency ”

3.2 Virtual agent

hypothesis new Gift() Is an expensive operation , You can put new Gift() Leave the operation to the agent “ Xiao Ming ” To carry out , agent “ Xiao Ming ” Will choose “ Xiaogang ” When you are in a good mood new Gift() . This is called “ Virtual agent ”. Virtual agents put some expensive objects , Delay creating it until you really need it .

var xiaoming = {
receiveGift: function(gift) {
xiaogang.listenGoodMood(function(){ // Monitor Xiaogang's good mood 
var gift = new Gift(); // Delay creation gift object 
xiaogang.receiveGift(gift)
})
}
}
 Copy code 

The protection agent is used to control the access of objects with different permissions to the target object , But in JavaScript It's not easy to implement a protection agent , Because you can't tell who accessed an object . Virtual agent is the most commonly used agent mode .

4. Virtual agent realizes picture preloading

If you give it to someone directly img Label node settings src attribute , Because the picture is too big or the network is not good , The position of the picture will be blank for some time . A common practice is to use one first loading Picture space , Then load the image asynchronously , When the image is loaded, fill it in img Node , This kind of scenario is very suitable for the use of virtual agents .

Examples are as follows :

First create an ontology object , This object is responsible for creating a img label , And provide an external setSrc Interface , The outside world calls this interface , You can give img Label settings src attribute :

var myImage = (function(){
var imgNode = document.createElement('img');
document.body.appendChild(imgNode);
return {
setSrc: function(src) {
imgNode.src = src;
}
}
})();
myImage.setSrc('http:// xxx.png');
 Copy code 

You can see , Before the picture is loaded , There is a period of blank space in the page .

Introduce proxy object proxyImage, Through this proxy object , Before the picture is actually loaded , A chrysanthemum diagram with space occupying will appear on the page loading.gif, To prompt the user that the picture is loading .

var myImage = (function(){
var imgNode = document.createElement('img');
document.body.appendChild(imgNode);
return {
setSrc: function(src) {
imgNode.src = src;
}
}
})();
var proxyImage = (function(){
var img = new Image;
img.onload = function(){
myImage.setSrc(this.src);
}
return {
setSrc: function(src) {
myImage.setSrc('file//xxx/loading.gif')
img.src = src;
}
}
})()
proxyImage.setSrc('http:// xxx.png')
 Copy code 

adopt proxyImage Indirect access to MyImage. proxyImage Control the customer's response to MyImage The interview of , And add some additional operations in the process , For example, before the real picture is loaded , The first img Node src Set as a local loading picture .

5. The meaning of agency

Some people may have questions , It's just a small picture preloading function , It can be done even without introducing any model , So what are the benefits of introducing the agent model ? Now let's get rid of the agent , Write a more common image preload function .

The preload image function without agent is implemented as follows :

var myImage = (function(){
var imgNode = document.createElement('img');
document.body.appendChild(imgNode);
var img = new Image;
img.onload = function(){
imgNode.src = img.src;
}
return {
setSrc: function(src) {
imgNode.src = 'file//xxx/loading.gif';
img.src = src
}
}
})();
myImage.setSrc('http:// xxx.png')
 Copy code 

To illustrate the meaning of agency , Introduce a principle of object-oriented design -- Principle of single responsibility

The principle of single responsibility refers to , Just one class ( It usually also includes objects and functions ) for , There should be only one cause for it to change . If an object has multiple responsibilities , It means that this object will become huge , There may be several reasons for its change . Object oriented design encourages the distribution of behavior among fine-grained objects , If an object has too many responsibilities , It's like coupling these responsibilities together , This coupling can lead to fragile and low cohesion designs . When change happens , The design may be accidentally damaged .

Responsibilities are defined as “ The cause of the change ”. In the previous code MyImage In addition to being responsible for img Node set src Outside , Also responsible for preloading images . When dealing with one of these responsibilities , It is possible that its strong coupling affects the implementation of another responsibility .

actually , All we need is to give img Node set src, Preloading images is just a icing on the cake . If you can put this operation in another object , It's a very good way . The role of agency is reflected here , The agent is responsible for preloading images , After the preload operation is completed , Relinquish the request to the ontology MyImage.

We have not changed or increased MyImage The interface of , But through proxy objects , In fact, new behaviors have been added to the system . This is in line with the open - Closed principle . to img Node set src And image preloading , Isolated in two objects , They can change each other without affecting each other . And even if one day you don't need preloading , Just change to the request ontology instead of the request proxy object .

6. Consistency between proxy and local interface

In the previous example , If one day we no longer need preloading , Then the proxy object is no longer needed , You can choose to request the ontology directly . The key is that both proxy objects and ontologies provide setSrc Method , In the eyes of customers , Proxy objects and ontologies are consistent , The process of the agent taking over the request is transparent to the user , Users don't know the difference between agents and ontologies , There are two advantages to doing so .

  • Users can safely request agents , He only cares about whether he can get the desired result
  • In any place where ontologies are used, they can be replaced by using proxies .

stay Java Such as language , Both agents and ontologies need to explicitly implement the same interface , On the one hand, interfaces ensure that they will have the same methods , On the other hand , Interface oriented programming caters to the principle of dependency inversion , Upward transformation through the interface , To avoid compiler type checking , Agents and ontologies can be replaced in the future .

If both the proxy object and the ontology object are a function ( Functions are also objects ), All functions must be executable , It can be considered that they also have the same “ Interface ”,

var myImage = (function(){
var imgNode = document.createElement('img');
document.body.appendChild(imgNode);
return function(src) {
imgNode.src = src;
}
})();
var proxyImage = (function(){
var img = new Image;
img.onload = function(){
myImage(this.src);
}
return function(src){
myImage('file//xxx/loading.gif');
img.src = src;
}
})();
proxyImage('http:// xxx.png');
 Copy code 

7. Virtual agent merge HTTP request

var synchronousFile = function(id) {
console.log(' Start syncing files ,id by :' + id);
}
var proxySynchronousFile = (function(){
var cache = [],
timer;
return function(id) {
cache.push(id);
if(timer) {
return;
}
timer = setTimeout(function(){
synchronousFile(cache.join(','));
clearTimeout(timer);
timer = null;
cache.length = 0;
}, 2000)
}
})()
var checkbox = document.getElementsByTagName('input');
for(var i=0,c; c=checkbox[i++];){
c.onclick = function(){
if(this.checked === true) {
proxySynchronousFile(this.id);
}
}
}
 Copy code 

8. Application of virtual agent in lazy loading

var miniConsole = (function(){
var cache = [];
var handler = function(ev){
if(ev.keyCode === 113){ // When the user presses F2 when , Start loading real miniConsole.js
var script = document.createElement('script');
script.onload = function(){
for(var i=0, fn; fn=cache[i++];) {
fn();
}
}
script.src = 'miniConsole.js';
document.getElementsByTagName('head')[0].appendChild(script);
document.body.removeEventListener('keydown', handler); // Load only once miniConsole.js
}
}
document.body.addEventListener('keydown',handler, false);
return {
log: function(){
var args = arguments;
cache.push(function(){
return miniConsole.log.apply(miniConsole, args)
})
}
}
})()
miniConsole.log(11)
 Copy code 

9. The caching proxy

It can provide temporary storage for some expensive operation results , In the next calculation , If the parameters passed in are the same as before , You can directly return the previously stored operation results

9.1 Calculate the product

var mult = function(){
var a = 1;
for(var i=0, l = arguments.length; i < l; i++) {
a = a * arguments[i];
}
return a;
}
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)
proxyMult(1,2,3,4) // Directly returns the previously cached calculation results 
 Copy code 

10. Creating proxies dynamically with higher-order functions

By passing in higher-order functions in a more flexible way , You can create cache proxies for various calculation methods . Now these calculations are passed as parameters into a factory dedicated to creating cache agents , We can multiply 、 Add 、 Subtraction, etc. create cache proxy

// Calculate the product 
var mult = function(){
var a = 1;
for(var i=0, l = arguments.length; i<l;i++) {
a = a * arguments[i];
}
return a;
}
// Calculate the sum 
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 agents 
var createProxyFactory = function(fn) {
var chache = {}
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))
alert(proxyMult(1,2,3,4))
alert(proxyPlus(1,2,3,4))
alert(proxyPlus(1,2,3,4))
 Copy code 

11. Other agency models

  • Firewall proxy : Controls access to network resources
  • Remote agent : Provide local representation of an object in different address spaces
  • Protection agency : Used when the object should have different access rights
  • Intelligent reference agent : Instead of a simple pointer , It performs some additional operations when accessing objects , For example, calculate the number of times an object is referenced
  • Copy agent on write : It is usually used to copy a large object . The write time replication agent delays the replication process , When the object is actually modified , Just copy it . The copy on write agent is a variant of the virtual agent ,DLL( Dynamic link library in operating system ) It is a typical application scenario .

stay JavaScript The most commonly used in development are virtual agents and cache agents .

版权声明
本文为[Xiao Guo is in Shenzhen]所创,转载请带上原文链接,感谢
https://javamana.com/2021/09/20210909122358706d.html

  1. Vous apprendrez à construire un serveur d'applet Wechat (https) à la main
  2. 作为一名程序员我不忘初心,Java最新实习面试经验总结,
  3. 作为一名Java面试者你应该知道的,2021最新Java常用开源库总结,
  4. 作为一个程序员,你觉得最大的悲哀是什么,2021年大厂Java岗面试必问,
  5. Configuration de l'environnement Java du système win10
  6. 作為一個程序員,你覺得最大的悲哀是什麼,2021年大廠Java崗面試必問,
  7. En tant que programmeur, quelle est la plus grande tristesse que vous ressentez? L'entrevue d'emploi Java de 2021 dans une grande usine vous demandera:
  8. Comme vous devriez le savoir en tant qu'intervieweur Java, 2021 dernier résumé des bibliothèques open source couramment utilisées pour Java,
  9. En tant que programmeur, je n'oublie pas le dernier résumé de mon expérience d'entrevue de stage en Java.
  10. 作為一名Java面試者你應該知道的,2021最新Java常用開源庫總結,
  11. New feature of Java 8. Stream (). Map (general programming method: collect. Groupingby)
  12. Computer graduation project java + SSM hospital registration system
  13. 作為一名程序員我不忘初心,Java最新實習面試經驗總結,
  14. 使用Docker部署Spring-Boot项目,论程序员成长的正确姿势,
  15. Conseils pour améliorer l'efficacité du Code Java mille fois
  16. 全网首发,我在华为做Java外包的真实经历!
  17. 全套Java视频百度云,终于找到一个看得懂的JVM内存模型了,
  18. 入职3个月的Java程序员面临转正,字节跳动 京东 360 网易面试题整理,
  19. Docker tutorial series (I) introduction to docker tutorial spring cloud mybatis distributed microservice Cloud Architecture
  20. 全網首發,我在華為做Java外包的真實經曆!
  21. Lancement de l'ensemble du réseau, je fais l'expérience réelle de l'externalisation Java à Huawei!
  22. Run around with money? Li Weijia fell into the storm of endorsement! In the face of collective hot discussion, personal attitude has become the focus of attention
  23. 全套Java視頻百度雲,終於找到一個看得懂的JVM內存模型了,
  24. Un ensemble complet de vidéos Java Baidu Cloud a finalement trouvé un modèle de mémoire JVM compréhensible.
  25. Déployez le projet Spring Boot avec docker, et parlez de la bonne posture pour que les programmeurs grandissent.
  26. 关于网络优化你必须要知道的重点,GC 堆排 Tomcat 算法题,
  27. 关于电商秒杀系统中防超卖处理方案简述,Java开发热门前沿知识,
  28. Les programmeurs Java qui sont entrés dans l'entreprise pendant trois mois ont dû faire face à une correction d'échelle, et les octets ont sauté dans le traitement des questions d'entrevue de JD 360 Netease.
  29. What is the new syntax of XX ≠ null in Java?
  30. Spring scheduled task cron expression (@ scheduled)
  31. Une brève description du plan de traitement anti - surproduction dans le système d'arrêt du commerce électronique et les connaissances de pointe du développement Java.
  32. Ce que vous devez savoir sur l'optimisation du réseau, c'est que le problème de l'algorithme Tomcat de gerbage GC,
  33. 凭借这份Java面试题集,成体系化的神级Java进阶笔记,
  34. 凭借这份Java面试题集,BAT大厂面试基础题集合,
  35. Docker Knowledge point collation
  36. Redis sur la réalisation élégante des tâches retardées
  37. 憑借這份Java面試題集,BAT大廠面試基礎題集合,
  38. Avec cet ensemble de questions d'entrevue Java, l'ensemble de questions de base d'entrevue de bat,
  39. Avec cet ensemble de questions d'entrevue Java, les notes avancées Java de niveau divin sont systématisées,
  40. Opérateurs arithmétiques et opérateurs de comparaison pour JavaScript, Introduction classique au développement web
  41. MySQL + +: slow query log analysis (I)
  42. Android Architect path 21 Responsive Programming RX Java thread transformation Principles
  43. Explorer le cadre open source Android - 1. Okhttp Source Analysis
  44. 分布式宝典:限流 缓存 通讯,Java开发中常见的一些问题面试专题,
  45. 分享面试经历的网站,腾讯大牛教你自己写Java框架!
  46. Expliquer les six principes de base du modèle de conception par des exemples réels
  47. Site Web pour partager vos expériences d'entrevue, Tencent Bull vous apprend à écrire votre propre cadre Java!
  48. Dictionnaire distribué: communication de cache limitée par le courant, sujets d'entrevue pour certaines questions courantes dans le développement Java,
  49. Another uncle circle man is angry! The high-quality acting skills make people admire and achieve the highlight of the ending of spring in Jade House
  50. 10. MySQL database import, export and authorization
  51. 9. MySQL data query
  52. 8. MySQL data operation DML
  53. 7. MySQL database table engine and character set
  54. 分享面試經曆的網站,騰訊大牛教你自己寫Java框架!
  55. Les points de connaissance de Java Real - time Video Download, Byte Jumping Java R & D post ont été divulgués à l'intérieur.
  56. Introduction au JavaScript chapitre 15 (objets, clairvoyance)
  57. 前方高能,Java程序员最大的悲哀是什么?
  58. Tencent private cloud MySQL solution tdsql
  59. 前方高能,Java程序員最大的悲哀是什麼?
  60. Quelle est la plus grande tristesse des programmeurs Java à l'avenir?