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://qdmana.com/2021/09/20210909122358706d.html

  1. Flutter: résoudre le futur blocage en utilisant Isolate
  2. Résumé des opérations courantes pour les données de structure de l'arbre frontal
  3. Ant Design Transfer Twin Tree Shuttle box "make Wheels"
  4. De la carte de pensée à la base et à l'approfondissement, prenez note de l'expérience d'entrevue d'un octet sautant le poste de recherche et développement Java.
  5. Apprenez les composants d'implémentation de vue et Publiez - les à NPM
  6. [Questions d'entrevue à haute fréquence] À vous de choisir
  7. Une faible connaissance de beginpath () provoque une superposition de style lors de la peinture d'un dessin en toile
  8. React Hooks, laisse - moi t'emmener étudier.
  9. Comment la copie profonde résout - elle les références circulaires?
  10. JavaScript Advanced Programming (3rd Edition) Reading note 6
  11. Analyse de l'URL
  12. Discussion préliminaire sur xss
  13. Solution: développement de la page Web Wechat, obtenir la fosse Piétinée par le flux d'entrée de la caméra via navigator.mediadevice.getusermedia ()
  14. Des milliers de questions d'entrevue sélectionnées n'ont pas encore ét é effacées.
  15. Les questions d'entrevue de niveau intermédiaire et avancé d'Android au fil des ans sont entièrement incluses, et l'algorithme est distribué microservice
  16. J'ai résumé toutes les questions d'entrevue.
  17. Compréhension de la réactivité des données de vue
  18. Note de service CSS (vi): Flex, page mobile et mise en page réactive
  19. Non-ASCII character ‘\xe5‘ in file kf1.py on line 4, but no encoding declared; see http://python.or
  20. 手把手教你搭建微信小程序服务器(HTTPS)
  21. JavaScript Review sketch - 1
  22. Analyse du bootstrap webpack
  23. sqli-labs-less-18 http头user agent+报错注入
  24. Génération de code nest pour l'outil CLI de nestjs
  25. JS | This
  26. Augmentation des variables
  27. The sinking gs8 raises its flag again. GAC motor's sales are falling endlessly. Is it the car or the people?
  28. Ren Hao's lunch at work today is president Hao wearing a sleeveless coat! Clean and handsome!
  29. Summary of basic knowledge points of JavaScript language (mind map)
  30. The new front-end lady asked: there was a 404 problem refreshing the page in Vue routing history mode
  31. Sqli Labs - less - 18 http header user agent + Error Reporting Injection
  32. Vous apprendrez à construire un serveur d'applet Wechat (https) à la main
  33. Non - ASCII character 'xe5' in file kf1.py on Line 4, but no Encoding declared;Voirhttp://python.or
  34. The new front-end lady asked: there was a 404 problem refreshing the page in Vue routing history mode
  35. 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:
  36. En tant que programmeur, je n'oublie pas le dernier résumé de mon expérience d'entrevue de stage en Java.
  37. Experts suggested that performers work with certificates, which triggered a collective heated debate. It is meaningless to be accused of repeating the mistakes
  38. The new front-end lady asked: there was a 404 problem refreshing the page in Vue routing history mode
  39. The appearance value of 200000 "Odyssey" is less than 100000, and has become the "sales champion" of household MPV
  40. 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.
  41. 350 questions d'entrevue Android partage, technologie d'architecture de cache
  42. The space is not vulgar, the configuration is rich, the leather is durable, less worry, and the high configuration is less than 100000!
  43. Vous permet de passer rapidement à travers l'entrevue de saut d'octets et d'aller de l'avant
  44. Résumé des questions d'entrevue technique d'Alibaba Baidu et d'autres grandes usines à la fin de l'année, et analyse de la dernière vraie question d'entrevue Android en 2021
  45. Avec cet ensemble de questions d'entrevue Java, l'ensemble de questions de base d'entrevue de bat,
  46. Avec cet ensemble de questions d'entrevue Java, les notes avancées Java de niveau divin sont systématisées,
  47. Opérateurs arithmétiques et opérateurs de comparaison pour JavaScript, Introduction classique au développement web
  48. Explorer le cadre open source Android - 1. Okhttp Source Analysis
  49. Module management of "free and open source" front-end spa project crudapi background management system based on Vue and Quasar (14)
  50. Partager l'expérience de l'examen et du développement de l'arrière - plan, en s'appuyant sur les questions d'entrevue et les réponses,
  51. Site Web pour partager vos expériences d'entrevue, Tencent Bull vous apprend à écrire votre propre cadre Java!
  52. Notes d'étape Android structurées, sélection de vrais problèmes d'entrevue Android
  53. Dictionnaire distribué: communication de cache limitée par le courant, sujets d'entrevue pour certaines questions courantes dans le développement Java,
  54. Tianci girlfriend Tangyuan attended the event for the second time. Her appearance was comparable to that of a star. The audience shouted that Tianci was blessed!
  55. Introduction au JavaScript chapitre 15 (objets, clairvoyance)
  56. La dernière revue scientifique de l'académicien Luo Liqun: architecture de la boucle neuronale pour stimuler la nouvelle Ia
  57. Basic knowledge of components in Vue "I"
  58. J'a i appris quelques petites choses sur l'entrevue et j'ai acheté un tutoriel en 19998.
  59. Dix minutes pour vous faire passer en revue les points de connaissance que Spring demande souvent, le chemin du retour Jedi d'un programmeur âgé de 35 ans,
  60. Want to know the implementation and application of single instance mode in the front end?