設(shè)計模式3.5 代理模式

字節(jié)跳動飛書內(nèi)推!
北京包个、杭州刷允、武漢、廣州碧囊、深圳树灶、上海,六大城市等你來投糯而。
感興趣的朋友可以私我咨詢&內(nèi)推天通,也可以通過鏈接直接投遞
海量HC熄驼,極速響應(yīng)像寒,快來和我成為同事吧。
今日頭條瓜贾、抖音诺祸、Tik Tok也可以內(nèi)推~

點擊進入我的博客

代理模式給某一個對象提供一個代理對象,并由代理對象控制對原對象對引用祭芦。

3.5.1 代理模式結(jié)構(gòu)

代理模式
  • 抽象主題(Subject)角色:聲明了真實主題和代理主題的共同接口
  • 代理主題(Proxy)角色:代理主題角色內(nèi)部含有對真實主題的引用筷笨,從而可以在任何時候操作真實主題對象;代理主題角色提供一個與真實主題角色相同的接口龟劲,以便可以在任何時候都可以替代真實主題控制對真實主題的引用胃夏,負責(zé)在需要的時候創(chuàng)建真實主題對象(和刪除真實主題對象);代理角色通常在將客戶端調(diào)用傳遞給真實的主題之前或之后昌跌,都要執(zhí)行某個操作仰禀,而不是單純地將調(diào)用傳遞給真實主題對象。
  • 真實主題(RealSubject)角色:定義了代理角色所代表的真實對象蚕愤。
public class Test {
    public static void main(String[] args) {
        Subject subject = new RealSubject();
        Subject proxy = new ProxySubject(subject);
        proxy.request(); // 此處通過代理類來執(zhí)行
    }
}

interface Subject {
    void request();
}

class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("RealSubject");
    }
}

class ProxySubject implements Subject {
    private Subject subject;

    public ProxySubject(Subject subject) {
        this.subject = subject;
    }

    @Override
    public void request() {
        System.out.println("ProxySubject");
    }
}

3.5.2 動態(tài)代理

自從JDK 1.3以后悼瘾,Java在java.lang.reflect庫中提供了一下三個類直接支持代理模式:ProxyInvocationHander审胸、Method亥宿。

動態(tài)代理步驟
  1. 創(chuàng)建一個真實對象
  2. 創(chuàng)建一個與真實對象有關(guān)的調(diào)用處理器對象InvocationHandler
  3. 創(chuàng)建代理,把調(diào)用處理器和要代理的類聯(lián)系起來Proxy.newInstance()
  4. 在調(diào)用處理對象的invoke()方法中執(zhí)行相應(yīng)操作
public class Test {
    public static void main(String[] args) {
        // 創(chuàng)建要被代理的實例對象
        Subject subject = new RealSubject();
        // 創(chuàng)建一個與被代理實例對象有關(guān)的InvocationHandler
        InvocationHandler handler = new ProxySubject(subject);
        // 創(chuàng)建一個代理對象來代理subject砂沛,被代理的對象subject的每個方法執(zhí)行都會調(diào)用代理對象proxySubject的invoke方法
        Subject proxySubject = (Subject) Proxy.newProxyInstance(Subject.class.getClassLoader(), new Class[]{Subject.class}, handler);
        // 代理對象執(zhí)行
        proxySubject.request();
    }
}

interface Subject {
    void request();
}

class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("RealSubject");
    }
}

class ProxySubject implements InvocationHandler {
    private Subject subject;

    public ProxySubject(Subject subject) {
        this.subject = subject;
    }

    /**
     * @param proxy 要代理的
     * @param method
     * @param args
     * @return
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before Proxy");
        Object obj = method.invoke(subject, args);
        System.out.println("After Proxy");
        return obj;
    }
}
  • 可以使用范型來創(chuàng)建ProxySubject
  • 可以使用匿名內(nèi)部類減少代碼數(shù)量請查看14.7節(jié)

3.5.3 細節(jié)

優(yōu)點
  1. 代理類和真實類分離烫扼,職責(zé)清晰。
  2. 在不改變真是累代碼的基礎(chǔ)上擴展了功能碍庵。
缺點
  1. 由于在客戶端和真實主題之間增加了代理對象映企,因此有些類型的代理模式可能會造成請求的處理速度變慢悟狱。
  2. 實現(xiàn)代理模式需要額外的工作,有些代理模式的實現(xiàn)非常復(fù)雜堰氓。
和適配器模式的關(guān)系

適配器模式的用意是改變所考慮對象的接口挤渐,而代理模式不能改變。

和裝飾模式
  • 裝飾模式應(yīng)當(dāng)為所裝飾的對象提供增強功能
  • 代理模式對對象的使用施加控制双絮,并不提供對象本身的增強功能
虛擬代理
  • 虛擬代理模式(Virtual PRoxy)會推遲真正所需對象實例化時間浴麻。在需要真正的對象工作之前,如果代理對象能夠處理囤攀,那么暫時不需要真正對象來出手软免。
  • 當(dāng)一個真實主題對象的加載需要耗費資源時,一個虛擬代理對象可以代替真實對象接受請求焚挠,并展示“正在加載”的信息膏萧,并在適當(dāng)?shù)臅r候加載真實主題對象。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蝌衔,一起剝皮案震驚了整個濱河市榛泛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌噩斟,老刑警劉巖挟鸠,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異亩冬,居然都是意外死亡,警方通過查閱死者的電腦和手機硼身,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門硅急,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人佳遂,你說我怎么就攤上這事营袜。” “怎么了丑罪?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵荚板,是天一觀的道長。 經(jīng)常有香客問我吩屹,道長跪另,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任煤搜,我火速辦了婚禮免绿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘擦盾。我一直安慰自己嘲驾,他們只是感情好淌哟,可當(dāng)我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著辽故,像睡著了一般徒仓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上誊垢,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天掉弛,我揣著相機與錄音,去河邊找鬼彤枢。 笑死狰晚,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的缴啡。 我是一名探鬼主播壁晒,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼业栅!你這毒婦竟也來了秒咐?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤碘裕,失蹤者是張志新(化名)和其女友劉穎携取,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體帮孔,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡雷滋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了文兢。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晤斩。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖姆坚,靈堂內(nèi)的尸體忽然破棺而出澳泵,到底是詐尸還是另有隱情,我是刑警寧澤兼呵,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布兔辅,位于F島的核電站,受9級特大地震影響击喂,放射性物質(zhì)發(fā)生泄漏维苔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一懂昂、第九天 我趴在偏房一處隱蔽的房頂上張望蕉鸳。 院中可真熱鬧,春花似錦、人聲如沸潮尝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽勉失。三九已至羹蚣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間乱凿,已是汗流浹背顽素。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留徒蟆,地道東北人胁出。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像段审,于是被迫代替她去往敵國和親全蝶。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,724評論 2 354

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

  • 設(shè)計模式概述 在學(xué)習(xí)面向?qū)ο笃叽笤O(shè)計原則時需要注意以下幾點:a) 高內(nèi)聚寺枉、低耦合和單一職能的“沖突”實際上抑淫,這兩者...
    彥幀閱讀 3,743評論 0 14
  • 整體Retrofit內(nèi)容如下: 1、Retrofit解析1之前哨站——理解RESTful 2姥闪、Retrofit解析...
    隔壁老李頭閱讀 3,236評論 2 10
  • 設(shè)計模式匯總 一始苇、基礎(chǔ)知識 1. 設(shè)計模式概述 定義:設(shè)計模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 3,940評論 1 15
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理筐喳,服務(wù)發(fā)現(xiàn)催式,斷路器,智...
    卡卡羅2017閱讀 134,654評論 18 139
  • 晚上避归,滿天的星星像明珠一樣閃亮荣月。一個孩子坐在院子里,靠著奶奶槐脏,仰起頭,對著夜空數(shù)星星撇寞。一顆顿天,兩顆,一直數(shù)到幾百...
    我愛更紗閱讀 161評論 0 0