設計模式系列| 代理模式
大家好,我是狼王,一個愛打球的程序員
這是設計模式的第十篇,這篇讓我們來認識一下代理模式
1、概述
代理模式是一種結(jié)構(gòu)型設計模式,讓你能夠提供對象的替代品或其占位符。代理控制著對于原對象的訪問, 并允許在將請求提交給對象前后進行一些處理。
2、適用場景
1)遠程代理 在不同的地址空間運行的遠程對象。本地代表對象的方法調(diào)用遠程對象。
2)虛擬代理 延遲初始化 (虛擬代理)。如果你有一個偶爾使用的重量級服務對象, 一直保持該對象運行會消耗系統(tǒng)資源時, 可使用代理模式。你無需在程序啟動時就創(chuàng)建該對象, 可將對象的初始化延遲到真正有需要的時候。
3)保護代理(安全代理) 訪問控制 , 如果你只希望特定客戶端使用服務對象, 而客戶端則是各種已啟動的程序 (包括惡意程序), 此時可使用代理模式。代理可僅在客戶端憑據(jù)滿足要求時將請求傳遞給服務對象。
4)智能指引 可在沒有客戶端使用某個重量級對象時立即銷毀該對象。代理會將所有獲取了指向服務對象或其結(jié)果的客戶端記錄在案。代理會時不時地遍歷各個客戶端, 檢查它們是否仍在運行。如果相應的客戶端列表為空, 代理就會銷毀該服務對象, 釋放底層系統(tǒng)資源。
3、實例
有以下場景:
小明和小雪是同班同學。
這天小明拿著花過來,說是同學小王送給小雪的。
第二天小明又拿著巧克力,還說是小王送給小雪的。
之后又同樣的送了娃娃。
代理模式實現(xiàn)。
創(chuàng)建送禮物接口:
/**
* 送禮物接口
*/
public interface ISendGifts {
/**
* 送花
*/
void sendFlower();
/**
* 送巧克力
*/
void sendChocolate();
/**
* 送娃娃
*/
void sendDolls();
}
創(chuàng)建小雪:
/**
* 小雪
*/
public class XiaoXue {
private String name;
public XiaoXue(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
創(chuàng)建小明(代理):
/**
* 小明
*/
public class XiaoMing implements ISendGifts {
private XiaoWang xiaoWang;
public XiaoWang getXiaoWang() {
return xiaoWang;
}
public void setXiaoWang(XiaoWang xiaoWang) {
this.xiaoWang = xiaoWang;
}
public XiaoMing(XiaoXue xiaoxue) {
this.xiaoWang = new XiaoWang(xiaoxue);
}
@Override
public void sendFlower() {
xiaoWang.sendFlower();
}
@Override
public void sendChocolate() {
xiaoWang.sendChocolate();
}
@Override
public void sendDolls() {
xiaoWang.sendDolls();
}
}
創(chuàng)建小王:
/**
* 小王
*/
public class XiaoWang implements ISendGifts{
private XiaoXue xiaoXue;
public XiaoWang(XiaoXue xiaoXue) {
this.xiaoXue = xiaoXue;
}
@Override
public void sendFlower() {
System.out.println(xiaoXue.getName() + ",我是小王,送你一朵小紅花");
}
@Override
public void sendChocolate() {
System.out.println(xiaoXue.getName() + ",我是小王,送你一塊巧克力");
}
@Override
public void sendDolls() {
System.out.println(xiaoXue.getName() + ",我是小王,送你一個洋娃娃");
}
}
創(chuàng)建測試類:
/**
* 測試類
*/
public class TestDemo {
public static void main(String[] args) {
XiaoXue xiaoXue = new XiaoXue("小雪");
XiaoMing xiaoMing = new XiaoMing(xiaoXue);
xiaoMing.sendFlower();
xiaoMing.sendChocolate();
xiaoMing.sendDolls();
}
}
結(jié)果:
小雪,我是小王,送你一朵小紅花
小雪,我是小王,送你一塊巧克力
小雪,我是小王,送你一個洋娃娃
4、分析
上面代碼達到了小王代替小明送禮物給小雪的過程,代碼結(jié)構(gòu)如下

代理邏輯如下圖:

5、總結(jié)
優(yōu)點:
1)你可以在客戶端毫無察覺的情況下控制服務對象。
2)如果客戶端對服務對象的生命周期沒有特殊要求, 你可以對生命周期進行管理。
3)即使服務對象還未準備好或不存在, 代理也可以正常工作。
4)開閉原則。你可以在不對服務或客戶端做出修改的情況下創(chuàng)建新代理。
缺點:
1)代碼復雜
2)增加響應的延時
好了。今天就說到這了,我還會不斷分享自己的所學所想,希望我們一起走在成功的道路上!
樂于輸出干貨的Java技術(shù)公眾號:狼王編程。公眾號內(nèi)有大量的技術(shù)文章、海量視頻資源、精美腦圖,不妨來關(guān)注一下!回復資料領取大量學習資源和免費書籍!

