Skip to content

Commit 1daf91d

Browse files
committed
2019.03.03
1 parent 66f3f1f commit 1daf91d

1 file changed

Lines changed: 165 additions & 2 deletions

File tree

Lines changed: 165 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,176 @@
1-
## 七、代理模式(Proxy Pattern)模式
1+
## 七、代理模式(Proxy Pattern)
22
### 1.概念介绍
3+
**代理模式(Proxy Pattern)**为其他对象提供一种代理,来控制这个对象的访问,代理是在客户端和真实对象之间的介质。
4+
5+
![装饰者模式1](http://images.pingan8787.com/20190303_proxy.png)
6+
7+
简单的理解:如我们需要请明星来做广告,我们会先通过联系Ta的经纪人,谈好条件才会给明星签合同。
38

49
### 2.优缺点和应用场景
510
#### 2.1优点
11+
* 职责单一且清晰。
12+
* 保护真实对象。
13+
* 开闭原则,高拓展性。
614

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

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

1124
### 3.基本案例
25+
这里我们以吃午饭问题来学习**代理模式**。通常情况下,我们会有两种方式解决午饭问题:“去餐厅吃”和“叫外卖”。
26+
去餐厅吃的话,我们就是自己过去吃饭了呗,如果是叫外卖,我们就会通过外卖小哥来拿到午饭才能吃起来。
27+
28+
* **去餐厅吃**(没有使用代理模式)
29+
30+
```js
31+
// 定义午饭类 参数 菜名
32+
let Lunch = function(greens){
33+
this.greens = greens;
34+
}
35+
Lunch.prototype.getGreens = function(){
36+
return this.greens;
37+
}
38+
// 定义我这个对象
39+
let leo = {
40+
buy: function(greens){
41+
console.log(`午饭吃${greens.getGreens()}`);
42+
}
43+
}
44+
// 去餐厅吃
45+
leo.buy(new Lunch('青椒炒肉')); // 午饭吃青椒炒肉
46+
```
47+
48+
* **叫外卖**(有使用代理模式)
49+
50+
```js
51+
// 定义午饭类 参数 菜名
52+
let Lunch = function(greens){
53+
this.greens = greens;
54+
}
55+
Lunch.prototype.getGreens = function(){
56+
return this.greens;
57+
}
58+
// 定义外卖小哥这个对象
59+
let brother = {
60+
buy: function(lunch){
61+
leo.buy(lunch.getGreens());
62+
}
63+
}
64+
// 定义我这个对象
65+
let leo = {
66+
buy: function(greens){
67+
console.log(`午饭吃${greens}`);
68+
}
69+
}
70+
// 叫外卖
71+
brother.buy(new Lunch('青椒炒肉')); // 午饭吃青椒炒肉
72+
```
73+
并且外卖小哥还会帮我们做一些其他事,比如帮我们带瓶可乐,我们改造`brother``leo`这2个对象,再看看效果:
74+
```js
75+
let brother = {
76+
buy: function(lunch){
77+
if(leo.needCola) leo.buyCola();
78+
leo.buy(lunch.getGreens());
79+
}
80+
}
81+
82+
let leo = {
83+
needCola: true,
84+
buy: function(greens){
85+
console.log(`午饭吃${greens}`);
86+
},
87+
buyCola: function(){
88+
console.log(`顺手买瓶可乐!`);
89+
}
90+
}
91+
brother.buy(new Lunch('青椒炒肉'));
92+
// 顺手买瓶可乐!
93+
// 午饭吃青椒炒肉
94+
```
95+
96+
### 4.保护代理
97+
还是借用 **3.基本案例** 的叫外卖的例子,我们现在要实现保护代理,而我们需要外卖小哥为了我们的身体健康,超过晚上9点,就不帮我们买可乐。
98+
还是改造上面买可乐的`brother`对象代码:
99+
```js
100+
let brother = {
101+
buy: function(lunch){
102+
let nowDate = new Date();
103+
if(nowDate.getHours() >= 21){
104+
console.log('亲,这么晚不要喝可乐哟!');
105+
}else{
106+
if(leo.needCola) leo.buyCola();
107+
leo.buy(lunch.getGreens());
108+
}
109+
}
110+
}
111+
brother.buy(new Lunch('青椒炒肉'));
112+
// 顺手买瓶可乐!
113+
// 午饭吃青椒炒肉
114+
```
115+
116+
### 5.虚拟代理
117+
虚拟代理能把一些开销大的对象,延迟到真正需要的时候才去创建和执行。
118+
我们这里举个图片懒加载的例子:
119+
这个案例参考自[JS设计模式-代理模式](https://juejin.im/entry/59d85109f265da065b66e25e).
120+
```js
121+
// 图片加载
122+
let ele = (function(){
123+
let node = document.createElement('img');
124+
document.body.appendChild(node);
125+
return{
126+
setSrc : function(src){
127+
node.src = src;
128+
}
129+
}
130+
})()
131+
132+
// 代理对象
133+
let proxy = (function(){
134+
let img = new Image();
135+
img.onload = function(){
136+
ele.setSrc(this.src);
137+
}
138+
return {
139+
setSrc : function(src){
140+
img.src = src;
141+
ele.setSrc('loading.png');
142+
}
143+
}
144+
})()
145+
146+
proxy.setSrc('example.png');
147+
```
148+
149+
### 6.缓存代理
150+
缓存代理是将一些开销大的运算结果提供暂存功能,当下次计算时,参数和之前一直,则将缓存的结果返回:
151+
这个案例参考自[JS设计模式-代理模式](https://juejin.im/entry/59d85109f265da065b66e25e).
152+
```js
153+
//计算乘积
154+
let mult = function(){
155+
let result = 1;
156+
for(let i = 0; i<arguments.length; i++){
157+
result *= arguments[i];
158+
}
159+
return result;
160+
}
161+
162+
// 缓存代理
163+
let proxy = (function(){
164+
let cache = {};
165+
return function(){
166+
let args = Array.prototype.join.call(arguments, '',);
167+
if(args in cache){
168+
return cache[args];
169+
}
170+
return cache[args] = mult.apply(this,arguments);
171+
}
172+
})();
173+
```
12174

13-
## 参考资料
175+
## 参考资料
176+
1. 《JavaScript Patterns》

0 commit comments

Comments
 (0)