設(shè)計模式之代理模式(Proxy模式)

  • 代理模式的引入
  • 代理模式的實例程序
  • 代理模式的分析

代理模式的引入

Proxy是代理人的意思,指的是代替別人進(jìn)行工作的人器赞。當(dāng)不一定需要本人親自去做的工作的時候,就可以尋找代理人去完成。
但在代理模式中贝椿,往往是相反的敢会,通常是代理人碰到工作曾沈,就交給被代理的對象去完成,代理人只完成一些準(zhǔn)備工作或者收尾工作鸥昏。
如果讀者了解過spring框架的話塞俱,就會知道aop也就是面向切面編程其實運用的就是動態(tài)代理模式,這可以讓被代理的對象專注于完成自己的本職工作吏垮,而代理對象可以進(jìn)行工作前的日志記錄障涯,時間計算,在工作之后進(jìn)行日志記錄膳汪,收尾工作等附加的功能唯蝶,需要正式做工作的時候就交給被代理去做。就像插了兩個刀到這個被代理的對象前后遗嗽。所以形象的叫做面向切面編程粘我。
關(guān)于動態(tài)代理模式和靜態(tài)代理模式,感興趣的讀者可以參考筆者的另一篇博文:
Java動態(tài)代理與靜態(tài)代理http://www.reibang.com/p/b5e340ec9551

代理模式的實例程序

我們會實現(xiàn)一個打印機痹换,向屏幕打印一串字符串征字,然后交給代理對象去完成這個功能。

首先看一下類圖:

image.png

Printer類:

package Proxy;

public class Printer implements Printable {
    private String name;
    public Printer() {
        heavyJob("正在生成Printer的實例");
    }
    public Printer(String name) {                   // 構(gòu)造函數(shù)
        this.name = name;
        heavyJob("正在生成Printer的實例(" + name + ")");
    }
    public void setPrinterName(String name) {       // 設(shè)置名字
        this.name = name;
    }
    public String getPrinterName() {                // 獲取名字
        return name;
    }
    public void print(String string) {              // 顯示帶打印機名字的文字
        System.out.println("=== " + name + " ===");
        System.out.println(string);
    }
    private void heavyJob(String msg) {             // 重活
        System.out.print(msg);
        for (int i = 0; i < 5; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
            System.out.print(".");
        }
        System.out.println("結(jié)束娇豫。");
    }
}

Printable接口:

package Proxy;

public interface Printable {
    public abstract void setPrinterName(String name);
    
    public abstract String getPrinterName();
    
    public abstract void print(String string); 
}

PrinterProxy類,利用反射機制匙姜,動態(tài)生成被代理的對象,并且延遲初始化到需要調(diào)用它的時候再初始化

package Proxy;

public class PrinterProxy implements Printable {
    private String name;            // 名字
    private Printable real;         // “本人”                 
    private String className;       // “本人”的類名       
    public PrinterProxy(String name, String className) {      // 構(gòu)造函數(shù)     
        this.name = name;
        this.className = className;                                                 
    }
    public synchronized void setPrinterName(String name) {  // 設(shè)置名字
        if (real != null) {
            real.setPrinterName(name);  // 同時設(shè)置“本人”的名字
        }
        this.name = name;
    }
    public String getPrinterName() {    // 獲取名字
        return name;
    }
    public void print(String string) {  // 顯示
        realize();
        real.print(string);
    }
    private synchronized void realize() {   // 生成“本人”
        if (real == null) {
            try {                                                                       
                real = (Printable)Class.forName(className).newInstance();               
                real.setPrinterName(name);                                              
            } catch (ClassNotFoundException e) {                                        
                System.err.println("沒有找到 " + className + " 類冯痢。");      
            } catch (Exception e) {                                                     
                e.printStackTrace();                                                    
            }                                                                           
        }
    }
}

Main類測試:

package Proxy;

public class Main {
    public static void main(String[] args) {
        Printable p = new PrinterProxy("Alice", "Proxy.Printer");                 
        System.out.println("現(xiàn)在的名字是" + p.getPrinterName() + "氮昧。");
        p.setPrinterName("Bob");
        System.out.println("現(xiàn)在的名字是" + p.getPrinterName() + "框杜。");
        p.print("Hello, world.");
    }
}

運行結(jié)果:

image.png

代理模式分析

代理模式中的角色:

  • Subject(主體)
    Subject角色定義了使proxy和realsubject角色之間具有一致性的接口。這個接口提供了一個使用的好處郭计,就是client不必卻分它使用的是代理對象還是真實對象霸琴。
    對應(yīng)實例中Printable角色

  • Proxy(代理人)
    Proxy角色會盡量處理來自Client角色的請求。只有當(dāng)自己不能處理的時候昭伸,就交給工作交給真實對象梧乘。代理對象只有在有必要時才會生成真實的對象。
    實例中對應(yīng)的是PrinterProxy對象庐杨。

  • RealSubject(真實對象)
    就是實際完成工作的對象选调,對應(yīng)實例中的Printer對象。

代理模式的類圖:

image.png
  • 用代理人來提升速度
    關(guān)鍵就在于延遲初始化灵份。
    我們可以等到需要使用到真實對象的功能才初始化仁堪。這樣的好處就是可以提升性能。從我們的實例中可能看不出這個優(yōu)勢填渠,假設(shè)我們有一個大型系統(tǒng)弦聂,如果我們都在系統(tǒng)啟動的時候,把所有功能初始化氛什,所有實例初始化莺葫,那么顯然系統(tǒng)的啟動將會變得很慢。但如果我們采用代理模式枪眉,那么就會在必須的時候捺檬,在初始化對象。這樣就加快了系統(tǒng)的啟動速度贸铜。

  • 代理和委托
    其實我們學(xué)習(xí)了那么多設(shè)計模式堡纬,是不是感覺委托簡直無處不在。幾乎每個設(shè)計模式都會用到委托蒿秦,代理模式也不意外烤镐,就是代理了對象委托了真實對象。
    因為委托可以是對象之間發(fā)生聯(lián)系渤早,互相調(diào)用湖雹。所以委托在很多設(shè)計模式中都存在躲叼。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蘑秽,更是在濱河造成了極大的恐慌元潘,老刑警劉巖帆精,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叉弦,死亡現(xiàn)場離奇詭異,居然都是意外死亡登下,警方通過查閱死者的電腦和手機茫孔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進(jìn)店門叮喳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人缰贝,你說我怎么就攤上這事馍悟。” “怎么了剩晴?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵锣咒,是天一觀的道長。 經(jīng)常有香客問我赞弥,道長毅整,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任绽左,我火速辦了婚禮悼嫉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拼窥。我一直安慰自己戏蔑,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布鲁纠。 她就那樣靜靜地躺著辛臊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪房交。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天伐割,我揣著相機與錄音候味,去河邊找鬼。 笑死隔心,一個胖子當(dāng)著我的面吹牛白群,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播硬霍,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼帜慢,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了唯卖?” 一聲冷哼從身側(cè)響起粱玲,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎拜轨,沒想到半個月后抽减,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡橄碾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年卵沉,在試婚紗的時候發(fā)現(xiàn)自己被綠了颠锉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡史汗,死狀恐怖琼掠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情停撞,我是刑警寧澤瓷蛙,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站怜森,受9級特大地震影響速挑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜副硅,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一姥宝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧恐疲,春花似錦腊满、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至省咨,卻和暖如春肃弟,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背零蓉。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工笤受, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人敌蜂。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓箩兽,卻偏偏與公主長得像,于是被迫代替她去往敵國和親章喉。 傳聞我的和親對象是個殘疾皇子汗贫,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 設(shè)計模式匯總 一、基礎(chǔ)知識 1. 設(shè)計模式概述 定義:設(shè)計模式(Design Pattern)是一套被反復(fù)使用秸脱、多...
    MinoyJet閱讀 3,948評論 1 15
  • 整體Retrofit內(nèi)容如下: 1落包、Retrofit解析1之前哨站——理解RESTful 2、Retrofit解析...
    隔壁老李頭閱讀 3,241評論 2 10
  • 工廠模式類似于現(xiàn)實生活中的工廠可以產(chǎn)生大量相似的商品摊唇,去做同樣的事情妥色,實現(xiàn)同樣的效果;這時候需要使用工廠模式。簡單...
    舟漁行舟閱讀 7,777評論 2 17
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理遏片,服務(wù)發(fā)現(xiàn)嘹害,斷路器撮竿,智...
    卡卡羅2017閱讀 134,701評論 18 139
  • Which type? Someone is like the Egypt pyramid. It seems...
    fb2e3d8145da閱讀 426評論 6 1