首页 > 编程语言 >【JS】170-JavaScript设计模式——代理模式

【JS】170-JavaScript设计模式——代理模式

时间:2022-10-13 15:34:30浏览次数:68  
标签:function buy greens JavaScript 代理 leo JS let 设计模式

【JS】170-JavaScript设计模式——代理模式_代理模式

七、代理模式(Proxy Pattern)

1.概念介绍

代理模式(Proxy Pattern) 为其他对象提供一种代理,来控制这个对象的访问,代理是在客户端和真实对象之间的介质。

【JS】170-JavaScript设计模式——代理模式_缓存_02

简单的理解:如我们需要请明星来做广告,我们会先通过联系Ta的经纪人,谈好条件才会给明星签合同。

2.优缺点和应用场景

2.1优点

  • 职责单一且清晰。
  • 保护真实对象。
  • 开闭原则,高拓展性。

2.2缺点

  • 由于在客户端和真实对象间添加代理对象,导致请求处理速度变慢。
  • 实现代理模式需要额外工作,有些代理模式实现起来非常复杂。

2.3应用场景

  • 需要隐藏或保护某个类,则为这个类添加代理。
  • 需要给不同访问者提供不同权限,则在代理类上做判断。
  • 需要为某个类添加功能,如添加日志缓存等,我们可以在代理的类做添加,而不管去改原来封装好的类。

3.基本案例

这里我们以吃午饭问题来学习代理模式。通常情况下,我们会有两种方式解决午饭问题:“去餐厅吃”和“叫外卖”。
去餐厅吃的话,我们就是自己过去吃饭了呗,如果是叫外卖,我们就会通过外卖小哥来拿到午饭才能吃起来。

  • 去餐厅吃(没有使用代理模式)
1. ​​// 定义午饭类 参数 菜名​​
2. ​​let Lunch = function(greens){​​
3. ​​ this.greens = greens;​​
4. ​​}​​
5. ​​Lunch.prototype.getGreens = function(){​​
6. ​​ return this.greens;​​
7. ​​}​​
8. ​​// 定义我这个对象​​
9. ​​let leo = {​​
10. ​​ buy: function(greens){​​
11. ​​ console.log(`午饭吃${greens.getGreens()}`);​​
12. ​​ }​​
13. ​​}​​
14. ​​// 去餐厅吃​​
15. ​​leo.buy(new Lunch('青椒炒肉')); // 午饭吃青椒炒肉​​
• 叫外卖(有使用代理模式)
16. ​​// 定义午饭类 参数 菜名​​
17. ​​let Lunch = function(greens){​​
18. ​​ this.greens = greens;​​
19. ​​}​​
20. ​​Lunch.prototype.getGreens = function(){​​
21. ​​ return this.greens;​​
22. ​​}​​
23. ​​// 定义外卖小哥这个对象​​
24. ​​let brother = {​​
25. ​​ buy: function(lunch){​​
26. ​​ leo.buy(lunch.getGreens());​​
27. ​​ }​​
28. ​​}​​
29. ​​// 定义我这个对象​​
30. ​​let leo = {​​
31. ​​ buy: function(greens){​​
32. ​​ console.log(`午饭吃${greens}`);​​
33. ​​ }​​
34. ​​}​​
35. ​​// 叫外卖​​
36. ​​brother.buy(new Lunch('青椒炒肉')); // 午饭吃青椒炒肉​​

并且外卖小哥还会帮我们做一些其他事,比如帮我们带瓶可乐,我们改造 ​​brother​​​和 ​​leo​​这2个对象,再看看效果:

1. ​​let brother = {​​
2. ​​ buy: function(lunch){​​
3. ​​ if(leo.needCola) leo.buyCola();​​
4. ​​ leo.buy(lunch.getGreens());​​
5. ​​ }​​
6. ​​}​​
7.
8. ​​let leo = {​​
9. ​​ needCola: true,​​
10. ​​ buy: function(greens){​​
11. ​​ console.log(`午饭吃${greens}`);​​
12. ​​ },​​
13. ​​ buyCola: function(){​​
14. ​​ console.log(`顺手买瓶可乐!`);​​
15. ​​ }​​
16. ​​}​​
17. ​​brother.buy(new Lunch('青椒炒肉'));​​
18. ​​// 顺手买瓶可乐!​​
19. ​​// 午饭吃青椒炒肉​​

4.保护代理

还是借用 3.基本案例 的叫外卖的例子,我们现在要实现保护代理,而我们需要外卖小哥为了我们的身体健康,超过晚上9点,就不帮我们买可乐。
还是改造上面买可乐的 ​​​brother​​对象代码:

1. ​​let brother = {​​
2. ​​ buy: function(lunch){​​
3. ​​ let nowDate = new Date();​​
4. ​​ if(nowDate.getHours() >= 21){​​
5. ​​ console.log('亲,这么晚不要喝可乐哟!');​​
6. ​​ }else{​​
7. ​​ if(leo.needCola) leo.buyCola();​​
8. ​​ leo.buy(lunch.getGreens());​​
9. ​​ }​​
10. ​​ }​​
11. ​​}​​
12. ​​brother.buy(new Lunch('青椒炒肉'));​​
13. ​​// 顺手买瓶可乐!​​
14. ​​// 午饭吃青椒炒肉​​

5.虚拟代理

虚拟代理能把一些开销大的对象,延迟到真正需要的时候才去创建和执行。
我们这里举个图片懒加载的例子: 这个案例参考自JS设计模式-代理模式.

1. ​​// 图片加载​​
2. ​​let ele = (function(){​​
3. ​​ let node = document.createElement('img');​​
4. ​​ document.body.appendChild(node);​​
5. ​​ return{​​
6. ​​ setSrc : function(src){​​
7. ​​ node.src = src;​​
8. ​​ }​​
9. ​​ }​​
10. ​​})()​​
11.
12. ​​// 代理对象​​
13. ​​let proxy = (function(){​​
14. ​​ let img = new Image();​​
15. ​​ img.onload = function(){​​
16. ​​ ele.setSrc(this.src);​​
17. ​​ }​​
18. ​​ return {​​
19. ​​ setSrc : function(src){​​
20. ​​ img.src = src;​​
21. ​​ ele.setSrc('loading.png');​​
22. ​​ }​​
23. ​​ }​​
24. ​​})()​​
25.
26. ​​proxy.setSrc('example.png');​​

6.缓存代理

缓存代理是将一些开销大的运算结果提供暂存功能,当下次计算时,参数和之前一直,则将缓存的结果返回:
这个案例参考自JS设计模式-代理模式.

1. ​​//计算乘积​​
2. ​​let mult = function(){​​
3. ​​ let result = 1;​​
4. ​​ for(let i = 0; i<arguments.length; i++){​​
5. ​​ result *= arguments[i];​​
6. ​​ }​​
7. ​​ return result;​​
8. ​​}​​
9.
10. ​​// 缓存代理​​
11. ​​let proxy = (function(){​​
12. ​​ let cache = {};​​
13. ​​ return function(){​​
14. ​​ let args = Array.prototype.join.call(arguments, '',);​​
15. ​​ if(args in cache){​​
16. ​​ return cache[args];​​
17. ​​ }​​
18. ​​ return cache[args] = mult.apply(this,arguments);​​
19. ​​ }​​
20. ​​})();​​

参考资料

  1. 《JavaScript Patterns》

【JS】170-JavaScript设计模式——代理模式_缓存_03


标签:function,buy,greens,JavaScript,代理,leo,JS,let,设计模式
From: https://blog.51cto.com/u_11887782/5753524

相关文章

  • videojs播放直播
    index.html引入css和js<linkhref="https://cdn.bootcdn.net/ajax/libs/video.js/7.10.1/alt/video-js-cdn.min.css"rel="stylesheet"><scripttype="text/javascrip......
  • 【JS】222-JS 函数的 6 个基本术语
    英文:Martin Novák 译文:reahinkhttps://zhuanlan.zhihu.com/p/61868946让我们谈谈什么是:lambdas(匿名函数)、first-classfunctions(头等函数)、higher-orderfunctions(高阶......
  • 45. JS Ajax请求(简明教程)
    1.前言Ajax全称“AsynchronousJavaScriptandXML”,译为“异步JavaScript和XML”,程序员们习惯称之为“阿贾克斯”,它并不是一种技术,而是多种技术的综合体,其中包括Ja......
  • 46. JS类型转换(强制类型转换+隐式类型转换)
    1.前言JavaScript 中有五种基本数据类型(其中包括String、Number、Boolean、Function、Symbol)、三种对象类型(其中包括Object、Date、Array)和两种特殊类型(其中包括Nul......
  • 【JS】80-如何优雅处理前端异常?
    前端一直是距离用户最近的一层,随着产品的日益完善,我们会更加注重用户体验,而前端异常却如鲠在喉,甚是烦人。一、为什么要处理异常?异常是不可控的,会影响最终的呈现结果,但是我们......
  • 【JS】89-用JavaScript实现的5个常见函数
    前言    在学习 JavaScript,或者前端面试中,有人会问你节流函数、防抖函数、递归函数等,本文分享了5个常见函数,希望对你有所帮助。    在 JavaScript 中有一些问题......
  • js时间戳,获取日期的总毫秒值
    时间戳vardate=newDate();console.log(date.valueOf());//valueof返回对象的原始值,date对象的原始值就是毫秒console.log(date.getTime());//返回一个时间的格林威......
  • 【JS】11-前端HTML5几种存储方式的总结
    接下来要好好总结一些知识,秋招来啦。。。虽然有好多知识都不大会,但是还是要努力一下,运气这种东西,谁知道呢~总体情况h5之前,存储主要是用​​cookies​​​。​​cookies​​......
  • 【JavaScript】13-JS中常见设计模式
    开发中,我们或多或少地接触了设计模式,但是很多时候不知道自己使用了哪种设计模式或者说该使用何种设计模式。本文意在梳理常见设计模式的特点,从而对它们有比较清晰的认知。Ja......
  • 【JS】14-精心收集的48个js代码片段分享
    该项目来自于 ​​Github​​​ 用户 ​​Chalarangelo​​​,目前已在 ​​Github​​​ 上获得了 ​​5000​​​ 多Star,精心收集了多达 ​​48​​​ 个有用的 ......