最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

Java設(shè)計(jì)模式-代理模式

2023-05-06 11:03 作者:小薯?xiàng)l學(xué)技術(shù)  | 我要投稿


img

簡(jiǎn)介

代理模式是一種結(jié)構(gòu)型設(shè)計(jì)模式,它可以讓我們通過一個(gè)代理對(duì)象來訪問一個(gè)真實(shí)的目標(biāo)對(duì)象,從而實(shí)現(xiàn)對(duì)目標(biāo)對(duì)象的功能擴(kuò)展或保護(hù)。代理模式的主要角色有三個(gè):

  • 抽象主題(Subject):定義了真實(shí)主題和代理主題的公共接口,使得在任何使用真實(shí)主題的地方都可以使用代理主題。

  • 真實(shí)主題(RealSubject):實(shí)現(xiàn)了抽象主題的接口,定義了真實(shí)的業(yè)務(wù)邏輯,是代理主題所代表的真實(shí)對(duì)象。

  • 代理主題(Proxy):也實(shí)現(xiàn)了抽象主題的接口,但是在調(diào)用真實(shí)主題的方法之前或之后,可以執(zhí)行一些額外的操作,從而對(duì)真實(shí)主題進(jìn)行控制或增強(qiáng)。

代理模式可以幫助我們解決以下幾種問題:

  • 當(dāng)我們無法或不想直接訪問一個(gè)對(duì)象時(shí),可以通過一個(gè)代理對(duì)象來間接訪問,例如遠(yuǎn)程代理、虛擬代理等。

  • 當(dāng)我們想要給一個(gè)對(duì)象提供額外的功能時(shí),可以通過一個(gè)代理對(duì)象來實(shí)現(xiàn),而不需要修改原有的對(duì)象,例如緩存代理、日志代理等。

  • 當(dāng)我們想要給一個(gè)對(duì)象增加一些訪問控制或安全保護(hù)時(shí),可以通過一個(gè)代理對(duì)象來實(shí)現(xiàn),例如防火墻代理、權(quán)限代理等。

實(shí)現(xiàn)

根據(jù)代理模式的定義,我們可以用以下的類圖來表示它的結(jié)構(gòu):

image-20230505112244447

其中,Client是客戶端類,它需要使用Subject接口提供的方法。Proxy是代理類,它持有一個(gè)RealSubject的引用,并且實(shí)現(xiàn)了Subject接口。RealSubject是真實(shí)類,它也實(shí)現(xiàn)了Subject接口,并且定義了具體的業(yè)務(wù)邏輯。

代理模式有多種類型,例如靜態(tài)代理、動(dòng)態(tài)代理等,代理模式也有自己的優(yōu)缺點(diǎn),使用時(shí)需要根據(jù)具體的場(chǎng)景和需求來選擇合適的類型和方式。

靜態(tài)代理實(shí)現(xiàn)

下面我們用Java代碼來實(shí)現(xiàn)一個(gè)靜態(tài)代理的例子:

// 抽象主題接口
public interface Subject {
? ?// 定義一個(gè)抽象方法
? ?void request();
}

// 真實(shí)主題類
public class RealSubject implements Subject {
? ?// 實(shí)現(xiàn)抽象方法
? ?@Override
? ?public void request() {
? ? ? ?// 真實(shí)的業(yè)務(wù)邏輯
? ? ? ?System.out.println("RealSubject is doing something...");
? ?}
}

// 代理主題類
public class Proxy implements Subject {
? ?// 持有一個(gè)真實(shí)主題的引用
? ?private RealSubject realSubject;

? ?// 構(gòu)造方法,傳入一個(gè)真實(shí)主題對(duì)象
? ?public Proxy(RealSubject realSubject) {
? ? ? ?this.realSubject = realSubject;
? ?}

? ?// 實(shí)現(xiàn)抽象方法
? ?@Override
? ?public void request() {
? ? ? ?// 在調(diào)用真實(shí)主題之前,可以執(zhí)行一些額外操作
? ? ? ?System.out.println("Proxy is doing something before...");
? ? ? ?// 調(diào)用真實(shí)主題的方法
? ? ? ?realSubject.request();
? ? ? ?// 在調(diào)用真實(shí)主題之后,可以執(zhí)行一些額外操作
? ? ? ?System.out.println("Proxy is doing something after...");
? ?}
}

// 客戶端類
public class Client {
? ?public static void main(String[] args) {
? ? ? ?// 創(chuàng)建一個(gè)真實(shí)主題對(duì)象
? ? ? ?RealSubject realSubject = new RealSubject();
? ? ? ?// 創(chuàng)建一個(gè)代理對(duì)象,并傳入真實(shí)主題對(duì)象
? ? ? ?Proxy proxy = new Proxy(realSubject);
? ? ? ?// 使用代理對(duì)象來調(diào)用抽象方法
?? ?proxy.request();
}
}運(yùn)行結(jié)果如下:
Proxy is doing something before...
RealSubject is doing something...
Proxy is doing something after...

從運(yùn)行結(jié)果可以看出,代理對(duì)象在調(diào)用真實(shí)對(duì)象的方法之前和之后,都執(zhí)行了一些額外的操作,從而對(duì)真實(shí)對(duì)象進(jìn)行了增強(qiáng)或控制。

動(dòng)態(tài)代理實(shí)現(xiàn)

動(dòng)態(tài)代理是一種特殊的代理模式,它可以在運(yùn)行時(shí)動(dòng)態(tài)地創(chuàng)建代理對(duì)象,而不需要事先定義代理類。動(dòng)態(tài)代理可以更靈活地適應(yīng)不同的場(chǎng)景和需求,但是也更復(fù)雜和難以理解。

這個(gè)例子是使用JDK動(dòng)態(tài)代理來實(shí)現(xiàn)一個(gè)日志代理,它可以在調(diào)用目標(biāo)對(duì)象的方法之前和之后,記錄相關(guān)的日志信息。代碼如下:

// 抽象主題接口
public interface Subject {
? ?// 定義一個(gè)抽象方法
? ?void request();
}

// 真實(shí)主題類
public class RealSubject implements Subject {
? ?// 實(shí)現(xiàn)抽象方法
? ?@Override
? ?public void request() {
? ? ? ?// 真實(shí)的業(yè)務(wù)邏輯
? ? ? ?System.out.println("RealSubject is doing something...");
? ?}
}

// 日志處理器類,實(shí)現(xiàn)了InvocationHandler接口,用于定義代理邏輯
public class LogHandler implements InvocationHandler {
? ?// 持有一個(gè)目標(biāo)對(duì)象的引用
? ?private Object target;

? ?// 構(gòu)造方法,傳入一個(gè)目標(biāo)對(duì)象
? ?public LogHandler(Object target) {
? ? ? ?this.target = target;
? ?}

? ?// 實(shí)現(xiàn)invoke方法,用于調(diào)用目標(biāo)對(duì)象的方法,并在之前和之后執(zhí)行日志操作
? ?@Override
? ?public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
? ? ? ?// 在調(diào)用目標(biāo)對(duì)象之前,記錄開始時(shí)間
? ? ? ?long startTime = System.currentTimeMillis();
? ? ? ?System.out.println("開始執(zhí)行" + method.getName() + "方法...");
? ? ? ?// 調(diào)用目標(biāo)對(duì)象的方法,并獲取返回值
? ? ? ?Object result = method.invoke(target, args);
? ? ? ?// 在調(diào)用目標(biāo)對(duì)象之后,記錄結(jié)束時(shí)間和耗時(shí)
? ? ? ?long endTime = System.currentTimeMillis();
? ? ? ?long duration = endTime - startTime;
? ? ? ?System.out.println("結(jié)束執(zhí)行" + method.getName() + "方法,耗時(shí)" + duration + "毫秒");
? ? ? ?// 返回結(jié)果
? ? ? ?return result;
? ?}
}

// 客戶端類
public class Client {
? ?public static void main(String[] args) {
? ? ? ?// 創(chuàng)建一個(gè)真實(shí)主題對(duì)象
? ? ? ?RealSubject realSubject = new RealSubject();
? ? ? ?// 創(chuàng)建一個(gè)日志處理器對(duì)象,并傳入真實(shí)主題對(duì)象
? ? ? ?LogHandler logHandler = new LogHandler(realSubject);
? ? ? ?// 使用Proxy類的靜態(tài)方法newProxyInstance來動(dòng)態(tài)地創(chuàng)建一個(gè)代理對(duì)象,傳入真實(shí)主題對(duì)象的類加載器、接口和處理器
? ? ? ?Subject proxy = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(), realSubject.getClass().getInterfaces(), logHandler);
? ? ? ?// 使用代理對(duì)象來調(diào)用抽象方法
? ? ? ?proxy.request();
? ?}
}


運(yùn)行結(jié)果如下:

開始執(zhí)行request方法...
RealSubject is doing something...
結(jié)束執(zhí)行request方法,耗時(shí)1毫秒

從運(yùn)行結(jié)果可以看出,代理對(duì)象在調(diào)用真實(shí)對(duì)象的方法之前和之后,都執(zhí)行了一些日志操作,從而對(duì)真實(shí)對(duì)象進(jìn)行了增強(qiáng)。

優(yōu)缺點(diǎn)

靜態(tài)代理模式

優(yōu)點(diǎn):

  • 代理模式可以實(shí)現(xiàn)對(duì)真實(shí)對(duì)象的功能擴(kuò)展或保護(hù),而不需要修改原有的對(duì)象,符合開閉原則。

  • 代理模式可以實(shí)現(xiàn)對(duì)真實(shí)對(duì)象的訪問控制或延遲加載,提高系統(tǒng)的性能和安全性。

  • 代理模式可以實(shí)現(xiàn)對(duì)真實(shí)對(duì)象的透明訪問,客戶端只需要使用抽象主題的接口,而不需要關(guān)心真實(shí)對(duì)象和代理對(duì)象的細(xì)節(jié)。

缺點(diǎn):

  • 代理模式會(huì)增加系統(tǒng)的復(fù)雜度和開銷,因?yàn)樾枰獎(jiǎng)?chuàng)建和維護(hù)代理對(duì)象。

  • 代理模式可能會(huì)降低系統(tǒng)的響應(yīng)速度,因?yàn)槊看握{(diào)用真實(shí)對(duì)象的方法都需要經(jīng)過代理對(duì)象。

動(dòng)態(tài)代理模式

優(yōu)點(diǎn):

  • 動(dòng)態(tài)代理可以在運(yùn)行時(shí)動(dòng)態(tài)地創(chuàng)建代理對(duì)象,而不需要事先定義代理類,這樣可以減少代碼量和提高開發(fā)效率。

  • 動(dòng)態(tài)代理可以根據(jù)不同的目標(biāo)對(duì)象和需求,靈活地生成不同的代理對(duì)象,這樣可以增加系統(tǒng)的可擴(kuò)展性和可維護(hù)性。

  • 動(dòng)態(tài)代理可以實(shí)現(xiàn)對(duì)目標(biāo)對(duì)象的透明訪問,客戶端只需要使用抽象主題的接口,而不需要關(guān)心真實(shí)對(duì)象和代理對(duì)象的細(xì)節(jié)。

缺點(diǎn):

  • 動(dòng)態(tài)代理需要使用反射和字節(jié)碼技術(shù)來生成代理對(duì)象,這樣會(huì)增加系統(tǒng)的復(fù)雜度和開銷,也可能會(huì)影響系統(tǒng)的性能和穩(wěn)定性。

  • 動(dòng)態(tài)代理需要遵循一些約束和限制,例如JDK動(dòng)態(tài)代理只能代理實(shí)現(xiàn)了接口的類,CGLIB動(dòng)態(tài)代理不能代理final類或方法等,這樣會(huì)降低系統(tǒng)的靈活性和通用性。

  • 動(dòng)態(tài)代理比靜態(tài)代理更難以理解和掌握,需要有一定的基礎(chǔ)知識(shí)和經(jīng)驗(yàn)才能使用好動(dòng)態(tài)代理。

運(yùn)用場(chǎng)景

  • 當(dāng)我們需要訪問一個(gè)遠(yuǎn)程對(duì)象時(shí),可以使用遠(yuǎn)程代理,它可以隱藏遠(yuǎn)程對(duì)象的位置和通信細(xì)節(jié),讓客戶端像訪問本地對(duì)象一樣訪問遠(yuǎn)程對(duì)象。

  • 當(dāng)我們需要?jiǎng)?chuàng)建一個(gè)開銷很大的對(duì)象時(shí),可以使用虛擬代理,它可以在真正需要的時(shí)候才創(chuàng)建真實(shí)對(duì)象,從而實(shí)現(xiàn)延遲加載和節(jié)省資源。

  • 當(dāng)我們需要給一個(gè)對(duì)象增加一些額外的功能時(shí),可以使用裝飾代理,它可以在不修改原有對(duì)象的情況下,給對(duì)象添加一些新的行為或?qū)傩浴?/p>

  • 當(dāng)我們需要給一個(gè)對(duì)象增加一些訪問控制或安全保護(hù)時(shí),可以使用保護(hù)代理,它可以根據(jù)不同的用戶或角色,對(duì)對(duì)象的訪問進(jìn)行限制或檢查。

  • 當(dāng)我們需要給一個(gè)對(duì)象增加一些日志記錄或性能監(jiān)控時(shí),可以使用日志代理或性能代理,它可以在調(diào)用對(duì)象的方法之前或之后,記錄相關(guān)的信息或數(shù)據(jù)。

總結(jié)

代理模式是一種常用的結(jié)構(gòu)型設(shè)計(jì)模式,它可以讓我們通過一個(gè)代理對(duì)象來間接訪問一個(gè)真實(shí)對(duì)象,從而實(shí)現(xiàn)對(duì)目標(biāo)對(duì)象的功能擴(kuò)展或保護(hù)。代理模式有三個(gè)主要角色:抽象主題、真實(shí)主題和代理主題。代理模式有多種類型,例如靜態(tài)代理、動(dòng)態(tài)代理、遠(yuǎn)程代理、虛擬代理等。代理模式有自己的優(yōu)缺點(diǎn),使用時(shí)需要根據(jù)具體的場(chǎng)景和需求來選擇合適的類型和方式。


Java設(shè)計(jì)模式-代理模式的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
启东市| 防城港市| 舟山市| 张家港市| 乡城县| 阿合奇县| 伊金霍洛旗| 莱西市| 虞城县| 米脂县| 屯留县| 肇东市| 永安市| 宿州市| 玉山县| 邓州市| 泰安市| 平度市| 六盘水市| 巴马| 阿克苏市| 伽师县| 历史| 谢通门县| 从江县| 洱源县| 平武县| 上蔡县| 泉州市| 白城市| 容城县| 会东县| 宜昌市| 东阳市| 游戏| 德庆县| 呼伦贝尔市| 洮南市| 平山县| 洪江市| 综艺|