代理模式

什么是代理模式?

類似于中介抠艾,我們面對的對象變成了中介,而不是用戶個體桨昙,例如租房子:

image-20220531153138579.png

1检号、靜態(tài)代理

角色分析:

  • 抽象角色:真實的目的性,一般是接口或者抽象類來解決
  • 真實角色:被代理的角色
  • 代理角色:代理真實角色蛙酪,代理真實角色后齐苛,一般進行一些附屬操作
  • 客戶:訪問代理對象的人,辦理真實業(yè)務的人

步驟:

1.接口

public interface Rent {
    //租房
    void rent();
    
}

2.真實角色

public class Landlord implements Rent{
    public void rent() {
        System.out.println("房東出租了房子~");
    }
}

3.代理角色

public class Proxy implements Rent {

    private Landlord landlord;

    public Proxy() {
    }

    public Proxy(Landlord landlord) {
        this.landlord = landlord;
    }

    //額外的操作
    public void seeHouse(){
        System.out.println("中介帶看房~");
    }
    public void hetong(){
        System.out.println("中介簽合同~");
    }
    public void fare(){
        System.out.println("中介收租~");
    }

    public void rent() {
        seeHouse();
        hetong();
        //真實的租房業(yè)務
        landlord.rent();
        fare();
    }
}

4.訪問

public class Client {

    public static void main(String[] args) {
        //房東
        Landlord landlord = new Landlord();
        //中介代理房東
        Proxy proxy = new Proxy(landlord);
        //租房業(yè)務
        proxy.rent();
    }
}

5滤否、結果

/**
中介帶看房~
中介簽合同~
房東出租了房子~
中介收租~
/

真實的租房業(yè)務還是房東脸狸,但是在中介代理后會進行了一些附加的操作最仑。

優(yōu)點

  • 真實的業(yè)務對象更加關注自己的業(yè)務藐俺,不用在意一些公共的業(yè)務
  • 公共交給代理炊甲,實現(xiàn)了業(yè)務分工
  • 在不修改目標對象的功能前提下, 能通過代理對象對目標功能擴展

缺點

  • 每一個實際的對象都對應一個代理對象,復雜度增加
  • 一旦公共接口增加方法,目標對象與代理對象都要維護

2欲芹、動態(tài)代理

  • 動態(tài)代理角色和靜態(tài)代理是一樣的
  • 動態(tài)代理的代理類是動態(tài)生成的卿啡,不是直接寫好的
  • 動態(tài)代理分兩大類:基于接口的動態(tài)代理,基于類的動態(tài)代理
    • 基于接口: JDK動態(tài)代理
    • 基于類:cglib
    • java字節(jié)碼實現(xiàn):javassist

需要理解兩個類:PorxyInvocationHandler

Porxy:提供了創(chuàng)建動態(tài)代理類和實例的靜態(tài)方法菱父,它也是由這些方法創(chuàng)建的所有動態(tài)代理類的超類颈娜,專門用來創(chuàng)建代理對象。

InvocationHandler:是調用代理實例的程序實現(xiàn)的接口浙宜,動態(tài)實現(xiàn)官辽,每個代理實例都有一個關聯(lián)的調用處理程序。 當在代理實例上調用方法時粟瞬,方法調用將被編碼并分派到其調用處理程序的invoke方法同仆。

還是以租房子為例:

1.接口

public interface Rent {

    void rent();

}

2.真實對象

public class Landlord implements Rent {
    public void rent() {
        System.out.println("房東出租了房子~");
    }
}

3.真實對象處理類

public class ProxyInvocationHandler implements InvocationHandler {
    //被代理的接口 這里可以通配
    private Object target;

    public void setTarget(Object target) {
        this.target = target;
    }

    //動態(tài)的獲取代理類 固定寫法
    public Object getPorxy(){
        /**
         * 參數(shù)
         *loader - 類加載器來定義代理類
         * interfaces - 代理類實現(xiàn)的接口列表
         * h - 調度方法調用的調用處理函數(shù)
         */
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }

    //處理被代理的實例 返回結果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        seeHouse();
        hetong();
        //真實的租房業(yè)務
//        this.log(method.getName());
        //處理真實的代理對象業(yè)務
        Object result = method.invoke(target,args);
        fare();
        return result;
    }

    //額外的操作
//    public void log(String msg){
//        System.out.println("操作了"+msg+"方法");
//    }
    public void seeHouse(){
        System.out.println("中介帶看房~");
    }
    public void hetong(){
        System.out.println("中介簽合同~");
    }
    public void fare(){
        System.out.println("中介收租~");
    }

}

4.測試

public static void main(String[] args) {
    //真實對象
    Landlord landlord = new Landlord();

    ProxyInvocationHandler handler = new ProxyInvocationHandler();
    //告訴處理器要代理的真實對象
    handler.setTarget(landlord);
    //獲取代理角色 動態(tài)生成的
    Rent porxy = (Rent) handler.getPorxy();
    //調用真實的業(yè)務
    porxy.rent();
}

結論:

這里的代理對象是通過處理類動態(tài)的獲取的,而且通過通配改造之后裙品,該處理類可以代理一類的需要代理的對象俗批,只要是實現(xiàn)了同一個接口的對象都可以動態(tài)的獲取到代理對象铸题。

優(yōu)點:

  • 基于靜態(tài)代理的基礎上赋元,一個動態(tài)代理類代理的是一個接口媳友,一般就是對應的一類業(yè)務
  • 一個動態(tài)代理類可以代理多個類褒脯,只要是實現(xiàn)了同一個接口的
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末其垄,一起剝皮案震驚了整個濱河市喧务,隨后出現(xiàn)的幾起案子哺徊,更是在濱河造成了極大的恐慌倦畅,老刑警劉巖驰弄,帶你破解...
    沈念sama閱讀 211,423評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蝠筑,死亡現(xiàn)場離奇詭異,居然都是意外死亡揩懒,警方通過查閱死者的電腦和手機什乙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,147評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來已球,“玉大人臣镣,你說我怎么就攤上這事≈橇粒” “怎么了忆某?”我有些...
    開封第一講書人閱讀 157,019評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長阔蛉。 經常有香客問我弃舒,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,443評論 1 283
  • 正文 為了忘掉前任聋呢,我火速辦了婚禮苗踪,結果婚禮上,老公的妹妹穿的比我還像新娘削锰。我一直安慰自己通铲,他們只是感情好,可當我...
    茶點故事閱讀 65,535評論 6 385
  • 文/花漫 我一把揭開白布器贩。 她就那樣靜靜地躺著颅夺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蛹稍。 梳的紋絲不亂的頭發(fā)上吧黄,一...
    開封第一講書人閱讀 49,798評論 1 290
  • 那天,我揣著相機與錄音唆姐,去河邊找鬼稚字。 笑死,一個胖子當著我的面吹牛厦酬,可吹牛的內容都是我干的胆描。 我是一名探鬼主播,決...
    沈念sama閱讀 38,941評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼仗阅,長吁一口氣:“原來是場噩夢啊……” “哼昌讲!你這毒婦竟也來了?” 一聲冷哼從身側響起减噪,我...
    開封第一講書人閱讀 37,704評論 0 266
  • 序言:老撾萬榮一對情侶失蹤短绸,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后筹裕,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體醋闭,經...
    沈念sama閱讀 44,152評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,494評論 2 327
  • 正文 我和宋清朗相戀三年朝卒,在試婚紗的時候發(fā)現(xiàn)自己被綠了证逻。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,629評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡抗斤,死狀恐怖囚企,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情瑞眼,我是刑警寧澤龙宏,帶...
    沈念sama閱讀 34,295評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站伤疙,受9級特大地震影響银酗,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,901評論 3 313
  • 文/蒙蒙 一黍特、第九天 我趴在偏房一處隱蔽的房頂上張望蛙讥。 院中可真熱鬧,春花似錦衅澈、人聲如沸键菱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至拭抬,卻和暖如春部默,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背造虎。 一陣腳步聲響...
    開封第一講書人閱讀 31,978評論 1 266
  • 我被黑心中介騙來泰國打工傅蹂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人算凿。 一個月前我還...
    沈念sama閱讀 46,333評論 2 360
  • 正文 我出身青樓份蝴,卻偏偏與公主長得像,于是被迫代替她去往敵國和親氓轰。 傳聞我的和親對象是個殘疾皇子婚夫,可洞房花燭夜當晚...
    茶點故事閱讀 43,499評論 2 348

推薦閱讀更多精彩內容