Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 556ac86

Browse files
✨ feat: 添加代理者模式文章
1 parent c336f6d commit 556ac86

File tree

2 files changed

+135
-2
lines changed

2 files changed

+135
-2
lines changed

‎Proxy/Proxy.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# 代理模式
2+
3+
> 代理模式是为一个对象提供一个代用品或者占位符,以便控制对它的访问。
4+
5+
代理模式是一种极为有趣的模式,生活中我们可以找到很多代理模式的场景。比如明星的经纪人,一般的商业活动不会直接跟明星接触,而是和经纪人谈,经纪人会把工作内容和报酬谈好之后在交给明星。
6+
7+
### 代理模式的简单实现
8+
9+
下面我们用一个明星买包的例子来解释下代理
10+
11+
当明星没有经济人 自己买包
12+
13+
```javascript
14+
// 定义一个包类
15+
class Bags {
16+
constructor(props) {
17+
this.name = props;
18+
}
19+
getName() {
20+
return this.name;
21+
}
22+
}
23+
24+
// 定义一个明星对象
25+
class Star {
26+
buyBag(bag) {
27+
console.log(`买到了一个${bag.getName()}`);
28+
}
29+
}
30+
31+
// 创建一个明星实例
32+
let star = new Star();
33+
star.buyBag(new Bags('Coach')); //买到了一个Coach包
34+
```
35+
36+
当明星让自己的助理去买包
37+
38+
```javascript
39+
// 定义一个包类
40+
class Bags {
41+
constructor(props) {
42+
this.name = props;
43+
}
44+
getName() {
45+
return this.name;
46+
}
47+
}
48+
49+
// 定义一个助理对象
50+
class Assistant {
51+
constructor(props) {
52+
this.star = props;
53+
}
54+
buyBag(bag) {
55+
this.star.buyBag(bag);
56+
}
57+
}
58+
59+
// 定义一个明星对象
60+
class Star {
61+
buyBag(bag) {
62+
console.log(`买到了一个${bag.getName()}`);
63+
}
64+
}
65+
66+
67+
68+
// 创建一个明星实例
69+
let star = new Star();
70+
let assistant = new Assistant(star);
71+
assistant.buyBag(new Bags('Coach')); //买到了一个Coach包
72+
```
73+
74+
此时我们就实现了一个简单的代理模式,但一般我们不会在这么简单的场景使用代理,反而徒增了代码的复杂度。
75+
76+
77+
78+
### 代理的使用场景
79+
80+
图片的懒加载是前端中比较会用到代理模式的场景,当网络不好的时候,图片的加载需要一段时间,这就会产生空白,影响用户体验,这时候在图片真正加载完之前,使用一张loading占位图片,等图片真正加载完在设置`src`属性,来实现图片的懒加载。
81+
82+
```javascript
83+
class ABigImage {
84+
constructor() {
85+
this.img = new Image();
86+
document.body.appendChild(this.img);
87+
}
88+
setSrc(src) {
89+
this.img.src = src;
90+
}
91+
}
92+
93+
class ProxyImage {
94+
constructor() {
95+
this.proxyImage = new Image();
96+
}
97+
98+
setSrc(src) {
99+
let bigImageObj = new ABigImage();
100+
bigImageObj.img.src = './local.png'; // 低清晰度图片url 或者本地图片
101+
this.proxyImage.src = src;
102+
this.proxyImage.onload = function() {
103+
bigImageObj.img.src = src;
104+
}
105+
}
106+
}
107+
108+
var proxyImage = new ProxyImage();
109+
proxyImage.setSrc('图片Url')
110+
```
111+
112+
在演示中我们可以感受到 (启用chrome的 Network 中的 Disable cache 并设置网速为 slow 3G 会让我们有更直观的感受)
113+
114+
![uG2uWQ.gif](https://s2.ax1x.com/2019/09/29/uG2uWQ.gif)
115+
116+
到这里图片的预加载已经实现,并且当我们的网速非常好,已经达到可以取消图片预加载的一些问题,那么我们可以直接使用`ABigImage``setSrc`方法,并且删除代理类,这样我们根本就不许要改动本体代码,这是易于维护的。
117+
118+
```
119+
// 网速很快时
120+
let aImage = new ABigImage();
121+
aImage.setSrc('图片url')
122+
```
123+
124+
#### 总结
125+
126+
- 代理模式符合开放封闭原则。
127+
- 代理模式会让代码易于维护。
128+
- 本体对象一般和代理对象拥有相同的方法,所以使用者并不知道请求的是本体对象还是代理对象。
129+
130+
131+
132+
> 本例中所有的例子均可在 [Demo](<https://github.com/Reaper622/JavaScript-DesignPatterns/tree/master/Proxy>)查看
133+

‎README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
JavaScript设计模式的相关学习
33

44
## 目录
5-
#### 创建型
5+
### 创建型
66
- [工厂模式](https://github.com/Reaper622/JavaScript-DesignPatterns/blob/master/Factory/Factory.md)
77
- [单例模式](https://github.com/Reaper622/JavaScript-DesignPatterns/blob/master/SinglePattern/SinglePattern.md)
88
- [原型模式](https://github.com/Reaper622/JavaScript-DesignPatterns/blob/master/Prototype/Prototype.md)
99

10-
#### 结构型
10+
### 结构型
1111
- [适配器模式](https://github.com/Reaper622/JavaScript-DesignPatterns/blob/master/Adapter/Adapter.md)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /