wordpress實(shí)訓(xùn)seo項(xiàng)目完整流程
代理模式(Proxy Pattern)
概念
代理模式(Proxy Pattern)是一種結(jié)構(gòu)型設(shè)計(jì)模式,代理對(duì)象在不改變目標(biāo)對(duì)象功能的前提下,通過(guò)控制對(duì)目標(biāo)對(duì)象的訪問(wèn),來(lái)實(shí)現(xiàn)延遲加載、權(quán)限控制、日志記錄等功能。代理模式可以通過(guò)提供一個(gè)中介對(duì)象,來(lái)控制客戶端和實(shí)際目標(biāo)對(duì)象之間的交互。
應(yīng)用場(chǎng)景
-
遠(yuǎn)程代理(Remote Proxy):為位于不同地址空間的對(duì)象提供代理,解決遠(yuǎn)程調(diào)用問(wèn)題。典型的例子是RMI(Remote Method Invocation),通過(guò)代理對(duì)象進(jìn)行遠(yuǎn)程方法調(diào)用。
-
虛擬代理(Virtual Proxy):為某些需要較高開(kāi)銷的對(duì)象提供代理,延遲其加載和創(chuàng)建。比如,大型圖片或文檔的加載可以通過(guò)虛擬代理來(lái)進(jìn)行,只有當(dāng)真正需要時(shí)才創(chuàng)建實(shí)際對(duì)象。
-
保護(hù)代理(Protection Proxy):用于控制對(duì)對(duì)象的訪問(wèn)權(quán)限。代理對(duì)象檢查調(diào)用者是否具有訪問(wèn)權(quán)限,只有在權(quán)限允許時(shí),才能訪問(wèn)目標(biāo)對(duì)象。
-
智能引用代理(Smart Reference Proxy):在訪問(wèn)對(duì)象時(shí)加入一些附加操作,如統(tǒng)計(jì)實(shí)際對(duì)象的引用次數(shù)、記錄日志、檢查鎖等。
-
緩存代理(Caching Proxy):代理可以緩存某些計(jì)算結(jié)果或操作結(jié)果,使得后續(xù)的相同請(qǐng)求不需要重復(fù)計(jì)算,提升系統(tǒng)性能。
注意點(diǎn)
- 代理類和實(shí)際類必須實(shí)現(xiàn)相同的接口:代理類的設(shè)計(jì)應(yīng)與目標(biāo)類保持一致,使得客戶端在使用代理類時(shí)與使用實(shí)際類沒(méi)有差異。
- 性能開(kāi)銷:盡管代理模式可以增加功能,但也可能增加系統(tǒng)開(kāi)銷,尤其是遠(yuǎn)程代理涉及到網(wǎng)絡(luò)傳輸時(shí)。
- 適合復(fù)雜的控制場(chǎng)景:代理模式尤其適合在需要控制訪問(wèn)、管理復(fù)雜操作、或添加額外處理邏輯的場(chǎng)景中使用。
核心要素
- Subject(抽象主題角色):定義代理類和目標(biāo)類的共同接口,使得代理類和目標(biāo)類可以被客戶端通過(guò)相同的方式調(diào)用。
- RealSubject(真實(shí)主題角色):定義目標(biāo)對(duì)象,實(shí)現(xiàn)真實(shí)的業(yè)務(wù)邏輯。
- Proxy(代理角色):負(fù)責(zé)控制對(duì)真實(shí)主題對(duì)象的訪問(wèn),通常會(huì)引用一個(gè)真實(shí)主題對(duì)象,并通過(guò)實(shí)現(xiàn)抽象主題接口來(lái)代理其操作。
Java代碼完整示例
代碼示例:靜態(tài)代理
// 抽象接口,定義真實(shí)主題和代理共同的行為
interface Subject {void request();
}// 真實(shí)主題,實(shí)現(xiàn)實(shí)際的業(yè)務(wù)邏輯
class RealSubject implements Subject {@Overridepublic void request() {System.out.println("真實(shí)主題執(zhí)行請(qǐng)求");}
}// 代理類,控制對(duì)真實(shí)主題的訪問(wèn)
class Proxy implements Subject {private RealSubject realSubject;@Overridepublic void request() {// 代理可以在調(diào)用真實(shí)對(duì)象之前執(zhí)行一些額外操作if (realSubject == null) {realSubject = new RealSubject();}System.out.println("代理:在調(diào)用真實(shí)對(duì)象前的額外操作");realSubject.request();System.out.println("代理:在調(diào)用真實(shí)對(duì)象后的額外操作");}
}// 客戶端
public class Client {public static void main(String[] args) {Subject proxy = new Proxy();proxy.request();}
}
輸出結(jié)果:
代理:在調(diào)用真實(shí)對(duì)象前的額外操作
真實(shí)主題執(zhí)行請(qǐng)求
代理:在調(diào)用真實(shí)對(duì)象后的額外操作
各種變形用法完整示例
-
虛擬代理(Virtual Proxy)
虛擬代理的主要目的是推遲大開(kāi)銷對(duì)象的創(chuàng)建,直到需要使用時(shí)才創(chuàng)建。典型例子是延遲加載大型圖片或文檔。代碼示例:
interface Image {void display(); }// 真實(shí)的圖像類,實(shí)際加載圖片 class RealImage implements Image {private String fileName;public RealImage(String fileName) {this.fileName = fileName;loadFromDisk();}private void loadFromDisk() {System.out.println("加載圖片: " + fileName);}@Overridepublic void display() {System.out.println("顯示圖片: " + fileName);} }// 虛擬代理類 class ProxyImage implements Image {private RealImage realImage;private String fileName;public ProxyImage(String fileName) {this.fileName = fileName;}@Overridepublic void display() {if (realImage == null) {realImage = new RealImage(fileName);}realImage.display();} }// 客戶端 public class VirtualProxyClient {public static void main(String[] args) {Image image = new ProxyImage("test.jpg");// 圖片首次顯示時(shí)加載image.display();System.out.println("");// 第二次調(diào)用時(shí)不需要加載image.display();} }
輸出結(jié)果:
加載圖片: test.jpg 顯示圖片: test.jpg顯示圖片: test.jpg
-
動(dòng)態(tài)代理(Dynamic Proxy)
動(dòng)態(tài)代理是在運(yùn)行時(shí)創(chuàng)建代理類,而不是在編譯時(shí)創(chuàng)建。在Java中,可以使用java.lang.reflect.Proxy
類來(lái)實(shí)現(xiàn)動(dòng)態(tài)代理,代理類可以動(dòng)態(tài)代理接口定義的所有方法。代碼示例:
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy;// 定義抽象接口 interface Service {void operation(); }// 實(shí)現(xiàn)接口的真實(shí)類 class RealService implements Service {@Overridepublic void operation() {System.out.println("執(zhí)行實(shí)際操作");} }// 動(dòng)態(tài)代理處理器 class DynamicProxyHandler implements InvocationHandler {private Object target;public DynamicProxyHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("動(dòng)態(tài)代理:在方法執(zhí)行前");Object result = method.invoke(target, args);System.out.println("動(dòng)態(tài)代理:在方法執(zhí)行后");return result;} }// 客戶端 public class DynamicProxyClient {public static void main(String[] args) {RealService realService = new RealService();Service proxyInstance = (Service) Proxy.newProxyInstance(realService.getClass().getClassLoader(),realService.getClass().getInterfaces(),new DynamicProxyHandler(realService));proxyInstance.operation();} }
輸出結(jié)果:
動(dòng)態(tài)代理:在方法執(zhí)行前 執(zhí)行實(shí)際操作 動(dòng)態(tài)代理:在方法執(zhí)行后
-
保護(hù)代理(Protection Proxy)
保護(hù)代理用于控制訪問(wèn)權(quán)限,可以通過(guò)代理來(lái)檢查調(diào)用者是否具備權(quán)限,只有在通過(guò)檢查時(shí),才能調(diào)用目標(biāo)對(duì)象的方法。代碼示例:
interface BankAccount {void deposit(double amount);void withdraw(double amount); }class RealBankAccount implements BankAccount {private double balance;public RealBankAccount(double balance) {this.balance = balance;}@Overridepublic void deposit(double amount) {balance += amount;System.out.println("存款成功,當(dāng)前余額: " + balance);}@Overridepublic void withdraw(double amount) {if (balance >= amount) {balance -= amount;System.out.println("取款成功,當(dāng)前余額: " + balance);} else {System.out.println("余額不足,取款失敗");}} }// 保護(hù)代理類 class ProtectionProxy implements BankAccount {private RealBankAccount realBankAccount;private String userRole;public ProtectionProxy(String userRole, double initialBalance) {this.userRole = userRole;realBankAccount = new RealBankAccount(initialBalance);}@Overridepublic void deposit(double amount) {realBankAccount.deposit(amount);}@Overridepublic void withdraw(double amount) {if ("ADMIN".equals(userRole)) {realBankAccount.withdraw(amount);} else {System.out.println("無(wú)權(quán)限取款");}} }// 客戶端 public class ProtectionProxyClient {public static void main(String[] args) {BankAccount adminAccount = new ProtectionProxy("ADMIN", 1000);adminAccount.withdraw(500);BankAccount userAccount = new ProtectionProxy("USER", 1000);userAccount.withdraw(500);} }
輸出結(jié)果:
取款成功,當(dāng)前余額: 500.0 無(wú)權(quán)限取款
總結(jié)
代理模式通過(guò)引入代理類為目標(biāo)對(duì)象提供額外的功能或控制。它適用于延遲加載、權(quán)限控制、日志記錄、遠(yuǎn)程調(diào)用等場(chǎng)景。代理模式可以分為靜態(tài)代理和動(dòng)態(tài)代理,并且具有多種變體,如虛擬代理、保護(hù)代理、遠(yuǎn)程代理等。