博主按:《每天一個設計模式》旨在初步領會設計模式的精髓,目前採用
javascript
(靠這吃飯)和python
(純粹喜歡)兩種語言實現。誠然,每種設計模式都有多種實現方式,但此小冊只記錄最直截了當的實現方式 ?
0. 專案地址
1. 什麼是代理模式?
代理模式的定義:為一個物件提供一種代理以方便對它的訪問。
代理模式可以解決避免對一些物件的直接訪問,以此為基礎,常見的有保護代理和虛擬代理。保護代理可以在代理中直接拒絕對物件的訪問;虛擬代理可以延遲訪問到真正需要的時候,以節省程式開銷。
2. 代理模式優缺點
代理模式有高度解耦、物件保護、易修改等優點。
同樣地,因為是通過“代理”訪問物件,因此開銷會更大,時間也會更慢。
3. 程式碼實現
3.1 python3 實現
class Image:
def __init__(self, filename):
self.filename = filename
def load_img(self):
print("finish load " + self.filename)
def display(self):
print("display " + self.filename)
# 藉助繼承來實現代理模式
class ImageProxy(Image):
def __init__(self, filename):
super().__init__(filename)
self.loaded = False
def load_img(self):
if self.loaded == False:
super().load_img()
self.loaded = True
def display(self):
return super().display()
if __name__ == "__main__":
proxyImg = ImageProxy("./js/image.png")
# 只載入一次,其它均被代理攔截
# 達到節省資源的目的
for i in range(0,10):
proxyImg.load_img()
proxyImg.display()
複製程式碼
3.2 javascript 實現
main.js
:
// main.js
const myImg = {
setSrc(imgNode, src) {
imgNode.src = src;
}
};
// 利用代理模式實現圖片懶載入
const proxyImg = {
setSrc(imgNode, src) {
myImg.setSrc(imgNode, "./image.png"); // NO1. 載入佔點陣圖片並且將圖片放入<img>元素
let img = new Image();
img.onload = () => {
myImg.setSrc(imgNode, src); // NO3. 完成載入後, 更新 <img> 元素中的圖片
};
img.src = src; // NO2. 載入真正需要的圖片
}
};
let imgNode = document.createElement("img"),
imgSrc =
"https://upload-images.jianshu.io/upload_images/5486602-5cab95ba00b272bd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1000/format/webp";
document.body.appendChild(imgNode);
proxyImg.setSrc(imgNode, imgSrc);
複製程式碼
main.html
:
<!-- main.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>每天一個設計模式 · 代理模式</title>
</head>
<body>
<script src="./main.js"></script>
</body>
</html>
複製程式碼
4. 參考
- 代理模式
- 《JavaScript 設計模式和開發實踐》