作者主頁(yè):Designer 小鄭
作者簡(jiǎn)介:3年JAVA全棧開發(fā)經(jīng)驗(yàn),專注JAVA技術(shù)、系統(tǒng)定制、遠(yuǎn)程指導(dǎo),致力于企業(yè)數(shù)字化轉(zhuǎn)型,CSDN博客專家,阿里云社區(qū)專家博主,藍(lán)橋云課講師。
一、什么是代理模式
代理模式是一種常用的設(shè)計(jì)模式,它提供了一個(gè)代理對(duì)象,用于控制對(duì)目標(biāo)對(duì)象的訪問。
在代理模式中,代理對(duì)象充當(dāng)了目標(biāo)對(duì)象的中間層,客戶端通過代理對(duì)象與目標(biāo)對(duì)象進(jìn)行交互。
在 Java 中,代理模式可以分為靜態(tài)代理和動(dòng)態(tài)代理兩種形式,請(qǐng)同學(xué)們做一個(gè)簡(jiǎn)單了解。
- 靜態(tài)代理 \color{red}{靜態(tài)代理} 靜態(tài)代理:在靜態(tài)代理中,代理類和目標(biāo)類都需要實(shí)現(xiàn)相同的接口或繼承相同的父類。代理類持有一個(gè)目標(biāo)對(duì)象的引用,并在調(diào)用目標(biāo)對(duì)象的方法之前或之后執(zhí)行一些附加操作。靜態(tài)代理的優(yōu)點(diǎn)是簡(jiǎn)單易懂,但缺點(diǎn)是需要為每個(gè)目標(biāo)類編寫一個(gè)代理類,當(dāng)目標(biāo)類較多時(shí)維護(hù)困難。
- 動(dòng)態(tài)代理 \color{red}{動(dòng)態(tài)代理} 動(dòng)態(tài)代理:動(dòng)態(tài)代理是在運(yùn)行時(shí)動(dòng)態(tài)生成代理類,無需為每個(gè)目標(biāo)類都編寫一個(gè)代理類。Java中提供了兩種動(dòng)態(tài)代理方式,一種是基于接口的動(dòng)態(tài)代理(JDK動(dòng)態(tài)代理),另一種是基于類的動(dòng)態(tài)代理(CGLIB動(dòng)態(tài)代理)。JDK動(dòng)態(tài)代理要求目標(biāo)對(duì)象實(shí)現(xiàn)一個(gè)接口,通過反射機(jī)制在運(yùn)行時(shí)創(chuàng)建代理類,代理類實(shí)現(xiàn)了目標(biāo)接口并持有目標(biāo)對(duì)象的引用。CGLIB動(dòng)態(tài)代理則是通過繼承目標(biāo)類創(chuàng)建代理類,代理類持有目標(biāo)對(duì)象的引用。動(dòng)態(tài)代理的優(yōu)點(diǎn)是靈活性高,可以代理任意類型的對(duì)象,但缺點(diǎn)是相比靜態(tài)代理稍微復(fù)雜一些。
代理模式的主要應(yīng)用場(chǎng)景包括以下 4 4 4 種。
- 遠(yuǎn)程代理 \color{red}{遠(yuǎn)程代理} 遠(yuǎn)程代理:為遠(yuǎn)程對(duì)象提供本地接口,隱藏網(wǎng)絡(luò)通信的復(fù)雜性。
- 虛擬代理 \color{red}{虛擬代理} 虛擬代理:根據(jù)需要?jiǎng)?chuàng)建開銷較大的對(duì)象,延遲對(duì)象的實(shí)例化。
- 安全代理 \color{red}{安全代理} 安全代理:控制對(duì)目標(biāo)對(duì)象的訪問權(quán)限。
- 智能代理 \color{red}{智能代理} 智能代理:在訪問目標(biāo)對(duì)象時(shí)添加額外的邏輯處理,如記錄日志、性能監(jiān)控等。
通過代理模式,我們可以實(shí)現(xiàn)對(duì)目標(biāo)對(duì)象的控制和增強(qiáng),提高系統(tǒng)的靈活性和可維護(hù)性。
二、代理模式實(shí)例
下面是一個(gè)簡(jiǎn)單的 Java 代理模式的示例代碼,展示了靜態(tài)代理和動(dòng)態(tài)代理兩種方式的實(shí)現(xiàn),請(qǐng)同學(xué)們復(fù)制到本地執(zhí)行。
2.1 靜態(tài)代理
// 定義接口
interface Subject {
void doSomething();
}
// 定義目標(biāo)類
RealSubject implements Subject {
@Override
public void doSomething() {
System.out.println("RealSubject doSomething");
}
}
// 定義代理類
class ProxySubject implements Subject {
private RealSubject realSubject;
public ProxySubject(RealSubject realSubject) {
this.realSubject = realSubject;
}
@Override
public void doSomething() {
System.out.println("Before doSomething");
realSubject.doSomething();
System.out.println("After doSomething");
}
}
// 使用示例
public class ProxyPatternExample {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
ProxySubject proxySubject = new ProxySubject(realSubject proxySubject.doSomething();
}
}
2.2 動(dòng)態(tài)代理
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 定義接口
interface Subject {
void doSomething();
}
// 定義目標(biāo)類
RealSubject implements Subject {
@Override
public void doSomething() {
System.out.println("RealSubject doSomething");
}
}
// 定義代理處理器
class ProxyHandler implements InvocationHandler {
private Object target;
public ProxyHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object, Method method, Object[] args) throws Throwable {
System.out.println("Before " + method.getName());
Object result = method.invoke(target, args);
System.out.println("After " + method.getName());
return result;
}
}
// 使用示例
public class ProxyPatternExample {
public static void main(String[] args) {
RealSubjectSubject = new RealSubject();
ProxyHandler handler = new ProxyHandler(realSubject);
Subject proxySubject = (Subject) Proxy.newProxyInstance(
realSubject.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(),
handler);
proxySubject.doSomething();
}
}
以上代碼演示了靜態(tài)代理和動(dòng)態(tài)代理兩方式的實(shí)現(xiàn)。
靜態(tài)代理需要為每個(gè)目標(biāo)類編寫一個(gè)代理類,而動(dòng)態(tài)代理則通過反射機(jī)制在運(yùn)行時(shí)動(dòng)態(tài)生成代理對(duì)象。
通過代理對(duì)象,我們可以在調(diào)用目標(biāo)對(duì)象的方法之前或之后執(zhí)行一些額外的邏輯。
三、代理模式的應(yīng)用場(chǎng)景
Java代理模式有很多應(yīng)用場(chǎng)景,以下是 6 6 6 個(gè)常見的應(yīng)用場(chǎng)景,請(qǐng)同學(xué)們認(rèn)真學(xué)習(xí)。
- 遠(yuǎn)程代理(Remote Proxy):將遠(yuǎn)程的對(duì)象通過代理進(jìn)行訪問,例如遠(yuǎn)程API調(diào)用、遠(yuǎn)程服務(wù)調(diào)用等,代理對(duì)象隱藏了網(wǎng)絡(luò)通信和復(fù)雜性,提供了簡(jiǎn)單的本地接口。
- 虛擬代理(Virtual Proxy):在訪問實(shí)際對(duì)象之前,通過代理對(duì)象延遲對(duì)象的實(shí)例化,例如加載大型資源(如圖片、視頻等)時(shí),可以先使用虛擬代理展示一個(gè)占位圖或提示信息,當(dāng)需要訪問實(shí)際對(duì)象時(shí)再進(jìn)行實(shí)例化。
- 安全代理(Security Proxy):控制對(duì)目標(biāo)對(duì)象的訪問權(quán)限,例如通過代理對(duì)象進(jìn)行身份驗(yàn)證、權(quán)限檢查等,在訪問目標(biāo)對(duì)象之前,代理對(duì)象可以執(zhí)行安全性檢查,確保只有合法的用戶可以訪問。
- 緩存代理(Cache Proxy):為目標(biāo)對(duì)象提供緩存機(jī)制,例如在訪問數(shù)據(jù)庫(kù)或其他耗時(shí)操作之前,代理對(duì)象可以先檢查緩存中是否存在相應(yīng)的結(jié)果,如果存在則直接返回緩存數(shù)據(jù),減少訪問真實(shí)對(duì)象的次數(shù)。
- 日志記錄(Logging Proxy):通過代理對(duì)象記錄系統(tǒng)的調(diào)用日志,例如記錄方法的入?yún)?、出參、耗時(shí)等信息,方便后續(xù)的分析和排查問題。
- 性能監(jiān)控(Performance Monitoring Proxy):通過代理對(duì)象監(jiān)控目標(biāo)對(duì)象的性能,例如記錄方法的執(zhí)行時(shí)間、調(diào)用次數(shù)等信息,用于性能優(yōu)化和監(jiān)控。
以上只是一些常見的應(yīng)用場(chǎng)景,實(shí)際上代理模式非常靈活,可以根據(jù)具體的需求進(jìn)行擴(kuò)展和應(yīng)用。
通過使用代理模式,我們可以在不改變目標(biāo)對(duì)象的情況下,控制和增強(qiáng)目標(biāo)對(duì)象的行為,提高系統(tǒng)的靈活性和可維護(hù)性。
文章來源:http://www.zghlxwxcb.cn/news/detail-727248.html
四、代理模式面試題
- 請(qǐng)解釋什么是代理模式,并舉例說明它的應(yīng)用場(chǎng)景。
- 請(qǐng)比較靜態(tài)代理和動(dòng)態(tài)代理的區(qū)別。
- Java 中如何實(shí)現(xiàn)靜態(tài)代理?請(qǐng)給出示例代碼。
- Java 中如何實(shí)現(xiàn)動(dòng)態(tài)代理?請(qǐng)給出示例代碼。
- 什么是 JDK 動(dòng)態(tài)代理?它的原理是什么?
- 什么是 CGLIB 動(dòng)態(tài)代理?它的原理是什么?
- 代理模式有哪些優(yōu)點(diǎn)和缺點(diǎn)?
- 在代理模式中,什么是代理類和目標(biāo)類?
- 代理模式和裝飾器模式有什么區(qū)別?
- 除了代理模式,還有哪些設(shè)計(jì)模式可以用來實(shí)現(xiàn)類似的功能?
文章來源地址http://www.zghlxwxcb.cn/news/detail-727248.html
到了這里,關(guān)于JAVA設(shè)計(jì)模式6:代理模式,用于控制對(duì)目標(biāo)對(duì)象的訪問的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!