每天一個設計模式·代理模式
博主按:《每天一個設計模式》旨在初步領會設計模式的精髓,目前採用javascript
(靠這吃飯
)和python
(純粹喜歡
)兩種語言實現。誠然,每種設計模式都有多種實現方式,但此小冊只記錄最直截了當的實現方式 :)
0. 專案地址
- ofollow,noindex" target="_blank">本節課程式碼
- 《每天一個設計模式》地址
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>