前言#
昨天已經(jīng)簡單的介紹了組合模式,今天再說一下代理模式。
代理模式也有很多種,例如直接代理,組合代理等等,但是中心思想就是保護(hù)被代理的類,這就是組合模式和代理的根本區(qū)別。
正文#
什么代理呢?
這個(gè)就完全不用解釋,每天我們都要遇到這類人:房產(chǎn)中介,旅游中介,婚姻中介等等,他們從提供服務(wù)的客戶得到對(duì)象的授權(quán),然后再對(duì)外提供這種服務(wù),代理就是中介。
首先看看什么是直接代理:
例如:我們聘請(qǐng)了律師幫我們打官司,這樣我們就不必和一些相關(guān)的機(jī)構(gòu)或人有過多的接觸,跟打官司有關(guān)的時(shí)候被律師全部代理負(fù)責(zé),保護(hù)我們自己的權(quán)益。
那么代碼就可以這么寫:
/**
* 代理類
* 返回代理對(duì)象
*/
public class MyProxy{
// 持有被代理類的對(duì)象
private My my;
public MyProxy(){
my = new My();
}
/**
* 被代理對(duì)象是私有類,外部無法直接訪問
*/
private class My{
...
}
/**
* 調(diào)用的是被代理類的方法,可以添加自己的邏輯
*/
public void Study(){
my.study();
}
...
}
這種方式有什么好處呢?
始終無法直接操作被代理類,完全被保護(hù),并且被代理類可以選擇不開放某些api。
如果是私密性非常高的類,絕對(duì)不允許私自修改的,那么肯定是需要考慮代理模式。
接下來再看看組合代理:
馬上就周末了,我們準(zhǔn)備出去旅游,計(jì)劃是這樣的:
1、早上出發(fā),旅游各種景點(diǎn)(需購買門票)。
2、中午吃飯(好不容易出去一趟,估計(jì)得提前預(yù)定)。
3、找一個(gè)高檔酒店,美美的睡一覺。
計(jì)劃完美,首先創(chuàng)建幾個(gè)類:
/**
* Created by li.zhipeng on 2017/7/27.
*
* 酒店類
*/
public class Hotel {
private static Hotel instance;
private Hotel(){
}
public static Hotel getInstance(){
if (instance == null){
instance = new Hotel();
}
return instance;
}
/**
* 預(yù)定方法
* */
public String reserve(){
return "預(yù)定酒店...\n";
}
/**
* 睡覺
* */
public String sleep(){
return "酒店的床又大又舒服哦~\n";
}
}
/**
* Created by li.zhipeng on 2017/7/27.
*
* 餐廳類
*/
public class Restaurant {
private static Restaurant instance;
private Restaurant(){
}
public static Restaurant getInstance(){
if (instance == null){
instance = new Restaurant();
}
return instance;
}
/**
* 預(yù)定方法
* */
public String reserve(){
return "預(yù)定飯店...\n";
}
/**
* 吃飯
* */
public String eat(){
return "這里的食物棒棒噠~\n";
}
}
/**
* Created by li.zhipeng on 2017/7/27.
*
* 游玩的地方
*/
public class PlayGround {
private static PlayGround instance;
private PlayGround(){
}
public static PlayGround getInstance(){
if (instance == null){
instance = new PlayGround();
}
return instance;
}
/**
* 預(yù)定方法
* */
public String reserve(){
return "購買游玩門票...\n";
}
/**
* 游玩
* */
public String play(){
return "玩的好開森~\n";
}
}
地方我們都已經(jīng)找好了,于是到了周末準(zhǔn)備出發(fā):
/**
* 開始游玩
* */
public String startPlay(){
StringBuilder sb = new StringBuilder();
// 購買游玩門票
sb.append(PlayGround.getInstance().reserve());
// 開始游玩
sb.append(PlayGround.getInstance().play());
// 飯店預(yù)定
sb.append(Restaurant.getInstance().reserve());
// 開始吃飯
sb.append(Restaurant.getInstance().eat());
// 酒店預(yù)定
sb.append(Hotel.getInstance().reserve());
// 開始睡覺
sb.append(Hotel.getInstance().sleep());
return sb.toString();
}
雖然計(jì)劃是順利執(zhí)行,但是感覺不太完美:
1、旅游景點(diǎn)還得現(xiàn)排隊(duì)買票(浪費(fèi)時(shí)間)。
2、吃飯還得看著時(shí)間提前預(yù)定。
3、酒店差點(diǎn)客滿,沒地方住。
第二次又準(zhǔn)備出去旅游了,吸取上一次的教訓(xùn),我下載了攜程旅游app(雖然我沒怎么用過),直接一條龍服務(wù):
/**
* Created by li.zhipeng on 2017/7/27.
*
* 旅游中介
*/
public class TravelProxy {
private static TravelProxy instance;
private TravelProxy(){
}
public static TravelProxy getInstance(){
if (instance == null){
instance = new TravelProxy();
}
return instance;
}
/**
* 旅游一條龍服務(wù)
* */
public void travelOneDragen(){
// 購買游玩門票
PlayGround.getInstance().reserve();
// 飯店預(yù)定
Restaurant.getInstance().reserve();
// 酒店預(yù)定
Hotel.getInstance().reserve();
}
}
訂票服務(wù)一條龍,我只要負(fù)責(zé)玩就好了,但是app拿出來掃一掃,一路完美:
/**
* 開始游玩
*/
public void startPlay() {
TravelProxy travelProxy = TravelProxy.getInstance();
// 一條龍服務(wù)
travelProxy.travelOneDragen();
// 開始游玩
PlayGround.getInstance().play();
// 開始吃飯
Restaurant.getInstance().eat();
// 開始睡覺
Hotel.getInstance().sleep();
}
以后要是再出去旅游,再使用一次就OK了,省時(shí)省力。
討論#
有些朋友可能要噴我:你這個(gè)組合代理不就是放了幾個(gè)類,往里面塞了一個(gè)方法,和組合模式有什么區(qū)別啊。
別著急,我們把 代理代理 和 組合模式 來做一個(gè)對(duì)比總結(jié)
中心思想
代理模式:保護(hù)被代理的多個(gè)類不被隨意控制,相對(duì)私密性高。
組合模式:僅僅是把多個(gè)類進(jìn)行組合使用,對(duì)私密性沒有提高。模式的目的
代理模式:最終希望得到的是一個(gè)工具類,一般使用單例模式。
組合模式:最終得到的是一個(gè)新的類,等同于被組合的類的性質(zhì)。類的擴(kuò)展
代理模式:相對(duì)來說,不太希望被代理發(fā)生巨大的變化,因?yàn)闀?huì)對(duì)業(yè)務(wù)造成影響。
組合模式:不太關(guān)心被組合的類發(fā)生變化,按照需求隨意組合。耦合性
代理模式:降低使用者和被代理類的耦合性。
組合模式:對(duì)耦合性無影響,因?yàn)槭褂谜咧店P(guān)心組合的結(jié)果,不關(guān)心組合的過程。
總結(jié)#
雖然組合模式和代理模式是有些區(qū)別,其實(shí)也可以看成一種模式的兩種不同形態(tài),設(shè)計(jì)模式從來不是單獨(dú)出現(xiàn)的,例如 代理+ 代理 = ?
當(dāng)然我們還可以在代理模式或者組合模式的基礎(chǔ)上繼續(xù)擴(kuò)展,例如加入工廠模式(為不同類型的設(shè)置代理)等等。
ok,周末要到了,祝大家周末愉快,下次再聊。