博主按:《天天一個設計模式》旨在初步領會設計模式的精髓,目前採用
javascript
(靠這吃飯)和python
(純粹喜歡)兩種語言實現。誠然,每種設計模式都有多種實現方式,但此小冊只記錄最直截了當的實現方式 :)javascript
代理模式的定義:爲一個對象提供一種代理以方便對它的訪問。html
代理模式能夠解決避免對一些對象的直接訪問,以此爲基礎,常見的有保護代理和虛擬代理。保護代理能夠在代理中直接拒絕對對象的訪問;虛擬代理能夠延遲訪問到真正須要的時候,以節省程序開銷。java
代理模式有高度解耦、對象保護、易修改等優勢。python
一樣地,由於是經過「代理」訪問對象,所以開銷會更大,時間也會更慢。git
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()
main.js
:github
// 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
:web
<!-- 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>