全文共1439字,預(yù)計(jì)閱讀時(shí)間:10分鐘
定義:
代理模式(Proxy),為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪(fǎng)問(wèn)。 代理模式是一種比較貼近于生活的設(shè)計(jì)模式,現(xiàn)實(shí)生活中也有很多代理模式的例子:
*
* 住酒店不一定需要親自到酒店去,還可以通過(guò)微信支付下的同程藝龍來(lái)訂酒店。
* 我們可以通過(guò)中介去找房子,不用直接跟房東溝通(現(xiàn)實(shí)生活中,我們更希望直接跟房東溝通)
* 春運(yùn)買(mǎi)票買(mǎi)不到,我們可以找黃牛替我們搶票
* 想訪(fǎng)問(wèn)國(guó)外的網(wǎng)站,可以使用代理服務(wù)器進(jìn)行訪(fǎng)問(wèn)。
代理模式通常解決的問(wèn)題是,我們沒(méi)有辦法直接訪(fǎng)問(wèn)某一個(gè)對(duì)象,但是卻想使用這個(gè)對(duì)象的一些功能,這個(gè)時(shí)候我們就可以創(chuàng)建一個(gè)代理對(duì)象,通過(guò)訪(fǎng)問(wèn)代理對(duì)象,間接的訪(fǎng)問(wèn)這個(gè)對(duì)象。
我們想去旅行,但是沒(méi)有辦法提前去目的地訂酒店,所以我們通過(guò)同程藝龍來(lái)訂酒店。同程藝龍就是一個(gè)代理對(duì)象,他和酒店一樣,提供了訂酒店的方法。
我們沒(méi)有渠道去直接聯(lián)系房東,所以我們可以通過(guò)中介公司租房,房東把租房這件事委托給了中介公司,這里中介公司就是一個(gè)代理對(duì)象。代理對(duì)象除了調(diào)用真實(shí)對(duì)象的方法,還可以對(duì)方法進(jìn)行增強(qiáng)。比如中介公司可以賺差價(jià)。
圖解:
?
?
?
這里可以看出,無(wú)論是代理對(duì)象和被代理對(duì)象,都實(shí)現(xiàn)了Subject接口,同時(shí)被代理對(duì)象作為代理對(duì)象的成員變量。這個(gè)結(jié)構(gòu)與裝飾模式非常像,下圖是裝飾模式的示意圖:
那么它們之間有什么區(qū)別呢?
首先從定義上可以看出,裝飾模式強(qiáng)調(diào)的是添加職責(zé),而代理模式強(qiáng)調(diào)的是間接訪(fǎng)問(wèn)。
其次從結(jié)構(gòu)設(shè)計(jì)上來(lái)說(shuō),裝飾模式是將一個(gè)個(gè)功能進(jìn)行拆分,使用時(shí)再動(dòng)態(tài)的進(jìn)行組裝,生成不同功能的對(duì)象。而代理模式卻是在編譯之前就已經(jīng)確定了代理對(duì)象和被代理對(duì)象之間的關(guān)系。
最后就使用上來(lái)說(shuō),裝飾模式需要客戶(hù)端去組裝對(duì)象,而代理模式卻只需要客戶(hù)端去調(diào)用代理對(duì)象,代理對(duì)象和被代理對(duì)象的關(guān)系被封裝到了代理對(duì)象中,對(duì)用戶(hù)而言是無(wú)感的。
實(shí)例:
這里舉一個(gè)訂酒店的實(shí)例,小趙在同程藝龍上預(yù)定了橘子酒店,這里酒店就是圖中的Subject,它提供了訂酒店、付款的方法,橘子酒店就是RealSubject,它是酒店的一個(gè)具體實(shí)現(xiàn)。而同程藝龍作為酒店的代理,提供優(yōu)質(zhì)的客戶(hù)服務(wù),其中包括訂酒店前的電話(huà)確認(rèn)、訂酒店后的客戶(hù)回訪(fǎng)、付款時(shí)提供紅包減免等。
代碼:
/** * 酒店. * * @author jialin.li * @date 2019-12-27 11:37 */ public interface
Hotel {/** 訂酒店 **/ void hotelBooking(String name); /** 付款 **/ double pay(); }
/** * 橘子酒店. * * @author jialin.li * @date 2019-12-27 13:17 */ public class
OrangeHotelimplements Hotel { @Override public void hotelBooking(String name) {
System.out.println(name+ ",歡迎入住橘子酒店"); } @Override public double pay() { return
120d; } } /** * 同程藝龍 * * @author jialin.li * @date 2019-12-27 13:20 */ public
class Elong implements Hotel{ private Hotel hotel; public Elong() { hotel = new
OrangeHotel(); } @Overridepublic void hotelBooking(String name) {
System.out.println(confirm(name)); hotel.hotelBooking(name);
System.out.println(callback(name)); } @Overridepublic double pay() { return
useHongbao(hotel.pay()); }private String confirm(String name){ return
"親愛(ài)的"+name+"您預(yù)定了橘子酒店,記得入住哦!"; } private String callback(String name){ return
"親愛(ài)的"+name+"您的入住已經(jīng)結(jié)束,有問(wèn)題請(qǐng)及時(shí)反饋!"; } private double useHongbao(double price){
return price - 50.0d; } } /** * 測(cè)試類(lèi). * * @author jialin.li * @date 2019-12-27
13:36*/ public class Main { public static void main(String[] args) { String
xiaozhao= "小趙"; Elong elong = new Elong(); elong.hotelBooking(xiaozhao);
System.out.print("共花費(fèi)了:"); System.out.println(elong.pay()); } }
結(jié)果:
親愛(ài)的小趙您預(yù)定了橘子酒店,記得入住哦! 小趙,歡迎入住橘子酒店 親愛(ài)的小趙您的入住已經(jīng)結(jié)束,有問(wèn)題請(qǐng)及時(shí)反饋! 共花費(fèi)了:70.0
有沒(méi)有什么問(wèn)題?
可以看出,我們?cè)诖眍?lèi)中直接引用了被代理對(duì)象,所以代理類(lèi)和被代理類(lèi)是一種一對(duì)一的關(guān)系,即我們需要為每一個(gè)被代理類(lèi),創(chuàng)建一個(gè)代理類(lèi)。
假設(shè)我們現(xiàn)在有一個(gè)打點(diǎn)的需求,要為系統(tǒng)中的一批對(duì)象增加記錄日志的方法,如果使用代理模式,就要為這一批對(duì)象創(chuàng)建代理類(lèi),這樣的工作量是無(wú)疑是巨大的。那么有沒(méi)有什么辦法可以讓我們可以少寫(xiě)或者不寫(xiě)代理類(lèi),卻能完成代理功能呢?這就要引出了我們要講的一個(gè)概念——?jiǎng)討B(tài)代理(動(dòng)態(tài)代理涉及到、反射類(lèi)加載的一些知識(shí),所以在下一篇文章中講解)
期待您的關(guān)注、推薦、收藏,同時(shí)也期待您的糾錯(cuò)和批評(píng)。
熱門(mén)工具 換一換
