代理設計模式
在我之前的部落格中,我探索了各種處理對象創建機制的創作設計模式。現在,是時候深入研究結構設計模式,它重點關注如何組合物件和類別以形成更大的結構,同時保持它們的靈活性和高效性。讓我們從代理設計模式開始
JavaScript 中的代理設計模式
代理設計模式是一種結構設計模式,它提供一個物件代表另一個物件。它充當控制對真實物件的存取的中介,添加附加行為,例如延遲初始化、日誌記錄、存取控製或緩存,而無需更改原始物件的程式碼。
在 JavaScript 中,代理程式是 Proxy 物件提供的內建功能,可讓您為屬性存取、賦值、函數呼叫等基本操作定義自訂行為。
我們什麼時候需要代理模式?
代理模式在以下情況下特別有用:
- 延遲初始化:您希望延遲建立資源密集型對象,直到需要它為止。
- 存取控制:您需要控制對物件的訪問,例如限制未經授權的存取或根據條件限制操作。
- 日誌記錄:您想要記錄物件上的操作(例如,屬性存取或方法呼叫)。
- 快取:您想要快取昂貴操作的結果以避免冗餘計算。
代理模式的組成部分
- 主題: 定義真實物件和代理的公共操作的介面。
- RealSubject: 執行實際工作的實際物件。
- 代理: 控制對 RealSubject 的存取的中介。
類比:
想像一下,您有一幅大畫想要向客人展示,但需要花費很多時間才能從儲藏室中取出它(因為它很重並且需要時間來搬運)。您決定使用這幅畫的小明信片圖像,在他們等待實際畫作被獲取時快速向他們展示,而不是每次都等待。
在這個比喻中:
- 大畫是真實的物體(就像需要時間載入的圖像)。
- 明信片是代理(一種輕量級替代品,直到真實物件準備好為止)。
- 一旦真正的畫作準備好,您就可以向客人展示實際的畫作。
現實世界的類比:
將房地產經紀人視為代理人。當你想買房子時,你不會立即參觀每棟房子(裝載實體)。相反,房地產經紀人(代理人)首先向您展示照片和描述。只有當你準備購買時(即,當你呼叫display()時),代理商才會安排看房(載入實體)。
真實範例:影像載入(虛擬代理)
讓我們使用 Web 應用程式中的圖像加載範例,我們希望延遲圖像的加載,直到用戶請求它(延遲加載)。代理可以充當佔位符,直到載入真實圖像。
以下是如何在 JavaScript 中實作代理設計模式。
範例:圖像載入代理
// Step 1: The real object class RealImage { constructor(filename) { this.filename = filename; this.loadImageFromDisk(); } loadImageFromDisk() { console.log(`Loading ${this.filename} from disk...`); } display() { console.log(`Displaying ${this.filename}`); } } // Step 2: The proxy object class ProxyImage { constructor(filename) { this.realImage = null; // no real image yet this.filename = filename; } display() { if (this.realImage === null) { // load the real image only when needed this.realImage = new RealImage(this.filename); } this.realImage.display(); // display the real image } } // Step 3: Using the proxy to display the image const image = new ProxyImage("photo.jpg"); image.display(); // Loads and displays the image image.display(); // Just displays the image (already loaded)
說明:
1)。真實影像:
- RealImage類別代表實際影像。
- 它以檔案名稱作為輸入,並模擬從磁碟載入影像的耗時過程(由 loadImageFromDisk 方法顯示)。
- 載入後,將使用顯示方法來顯示圖片。
2)。代理圖像:
- ProxyImage類別充當RealImage的替代品。它不會立即載入真實圖像。
- 它包含對真實圖像的引用(但最初它是空的,因為真實圖像尚未加載)。
- 當您在代理程式上呼叫顯示方法時,它會檢查真實圖像是否已載入。如果沒有,它會先加載,然後顯示。
3)。用法:
- 當我們建立 ProxyImage 實例時,實際映像尚未載入(因為它是資源密集的)。
- 第一次呼叫 display 時,代理程式會載入圖片(使用 RealImage 類別),然後顯示它。
- 第二次呼叫display時,真實圖片已經載入完畢,所以只顯示圖片,不再載入。
內建Proxy對象
ES6 代理由一個代理建構函式組成,建構函式接受目標和處理程序作為參數
const proxy = new Proxy(target, handler)
這裡,target代表應用代理的對象,而handler是一個特殊的對象,定義了代理的行為。
處理程序物件包含一系列具有預先定義名稱的可選方法,稱為陷阱方法(例如 apply、get、set 和 has),當對代理實例執行對應操作時,這些方法會自動呼叫。
讓我們透過使用內建代理實作計算器來理解這一點
// Step 1: The real object class RealImage { constructor(filename) { this.filename = filename; this.loadImageFromDisk(); } loadImageFromDisk() { console.log(`Loading ${this.filename} from disk...`); } display() { console.log(`Displaying ${this.filename}`); } } // Step 2: The proxy object class ProxyImage { constructor(filename) { this.realImage = null; // no real image yet this.filename = filename; } display() { if (this.realImage === null) { // load the real image only when needed this.realImage = new RealImage(this.filename); } this.realImage.display(); // display the real image } } // Step 3: Using the proxy to display the image const image = new ProxyImage("photo.jpg"); image.display(); // Loads and displays the image image.display(); // Just displays the image (already loaded)
使用代理程式的最佳部分是:
- 代理物件繼承了原Calculator類別的原型。
- 透過代理設置的陷阱來避免突變。
代碼說明
1)。 原型繼承:
- 代理人不會幹擾 **Calculator ** 類別的原始原型。
- 檢查 proxiedCalculator.proto === Calculator.prototype 來確認這一點。結果將是true。
2)。 處理 getOperations:
- get 陷阱攔截代理物件上的屬性存取。
- 我們使用 Reflect.get 安全地存取原始物件的屬性和方法。
3)。 防止突變:
每當嘗試修改目標物件上的任何屬性時,設定陷阱都會引發錯誤。這確保了不變性。
4)。 透過代理人使用原型方法:
代理允許存取加、減、乘、除等方法,所有這些方法都在原始物件的原型上定義。
這裡要觀察的重點是:
- 保留原型繼承:代理保留對所有原型方法的訪問,使其行為類似於原始計算器。
- 防止突變: 設定陷阱可確保計算器物件的內部狀態不會意外變更。
- 安全存取屬性和方法: get 陷阱確保僅存取有效的屬性,從而提高穩健性。
如果您已經做到了這一步,請不要忘記按讚❤️,並在下面發表評論以提出任何問題或想法。您的回饋對我來說至關重要,我很樂意收到您的來信!
以上是代理設計模式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

Python和JavaScript在開發環境上的選擇都很重要。 1)Python的開發環境包括PyCharm、JupyterNotebook和Anaconda,適合數據科學和快速原型開發。 2)JavaScript的開發環境包括Node.js、VSCode和Webpack,適用於前端和後端開發。根據項目需求選擇合適的工具可以提高開發效率和項目成功率。

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。1)C 用于解析JavaScript源码并生成抽象语法树。2)C 负责生成和执行字节码。3)C 实现JIT编译器,在运行时优化和编译热点代码,显著提高JavaScript的执行效率。
