那些你要知道的設計模式之-代理

一.定義

  1. 將一個復雜的構建與其表示相分離,使得同樣的構建過程可以創(chuàng)建不同的表示。

代理在結構上類似裝飾著,但目的不同,裝飾者模式為對象加上行為,而代理則是控制訪問 代理為另一個對象提供代表,以便客戶對對象的訪問

二.作用

  • 職責清晰真實的角色就是實現實際的業(yè)務邏輯,不用關心其他非本職責的事務,通過后期的代理
    完成一件事務,附帶的結果就是編程簡潔清晰。
  • 高擴展性

三.案例

本章將講解普通代理和動態(tài)代理兩種代理方式

  • 普通代理
    大學畢業(yè)之后大學生們就開始前往不同的城市參加工作,有些公司提供住房還好,但是這種可能性基本不大,于是乎就得考慮住房問題,這個時候市場上就出現了房屋中介商,專門解決這樣類似的問題。下面是簡單的示意圖
普通代理模式

IHouse接口有兩個方法房屋位置和房屋大小

public interface IHouse {

    //位置
    void location(String address);

    //大小
    void size(int size);
}

實現類House,這個類主要用來實現具體的業(yè)務邏輯,這里只打印這些信息,

public class House implements IHouse {

    @Override
    public void location(String address) {
        System.out.println(address);
    }

    @Override
    public void size(int size) {
        System.out.println(size+"平方");
    }

}

下面是代理模式的核心代理類,通過構造函數定義一個需要被代理的對象,同時它還可以具備自己的方法,作為一個房屋代理者,它還可以告訴你租房所需的費用

public class HomeProxy implements IHouse {

    private IHouse house;

    //構造函數定義一個租房
    public HomeProxy() {
        this.house = new House();
    }

    @Override
    public void location(String address) {
        this.house.location(address);
    }

    @Override
    public void size(int size) {
        this.house.size(size);
        cost(size);
    }


    //合計
    public void cost(int size) {
        System.out.println(size * 5 + tip(size)+"$");
    }


    //中介費
    public double tip(int size) {
        return size * 5 * 0.35;
    }

}

我們模擬一下租房的過程,如下所示:

public static void main(String[] args) {

        //創(chuàng)建一個房屋中介商
        IHouse proxy = new HomeProxy(house);
        //租房的位置
        proxy.location("上海");
        //租房的大小
        proxy.size(100);

    }

運行結果如下:
上海
100平方
675.0$
這種模式下通過構造函數定義一個代理對象,進行代理。調用者只需要知道代理類是誰就可以了,結構更加清晰,屏蔽了
真實角色的變更對高層模塊的影響,真是角色只需要實現接口,實現具體的業(yè)務邏輯,想怎么改就怎么改,提高了擴展性


  • 動態(tài)代理

動態(tài)代理需要實現InvocationHandler接口產生一個代理對象,InvocationHandler是JDK本身就提供好的的動態(tài)代理接口,這里用HomeIH去實現這個接口

public class HomeIH implements InvocationHandler {

    //被代理的實例
    Object obj;

    //我要代理誰
    public HomeIH(Object _obj) {
        this.obj = _obj;
    }

    //調用被代理的方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        //方法執(zhí)行之前
        System.out.println("before  " + method.getName());
        //執(zhí)行被代理的方法
        Object result = method.invoke(this.obj, args);
        return result;
    }
}

這樣寫之后所有方法都由該Handler來進行處理,所有被代理的方法都由invoke方法去執(zhí)行,invoke的三個參數分別為proxy(代理對象 ),method(被調用方法),args(被調用方法的參數)還是延續(xù)上面的代碼,只需將main函數修改如下

 public static void main(String[] args) {

        //被代理實例
        IHouse house = new House();
        //通過構造函數傳入到Handler中
        HomeIH handler = new HomeIH(house);
        //動態(tài)產生一個代理者
        IHouse proxy = (IHouse) Proxy.newProxyInstance(house.getClass().getClassLoader(),new Class[]{IHouse.class},handler);
        //租房的位置
        proxy.location("上海");
        //租房的大小
        proxy.size(100);

    }

運行之后看結果:
before location
上海
before size
100平方
看到沒這就是動態(tài)代理,還是通過代理去租房,和普通代理的區(qū)別就是,動態(tài)代理不用創(chuàng)建代理類,不用實現方法接口,而且更加的靈活,更加的具備擴展性 ,當然,JDK的動態(tài)代理有一個需要注意的地方,這里的每個委托類都必須是要有接口的,如果你問我,沒有實現接口能不能被代理,我說能

四.總結

代理類不僅僅是一個隔離客戶端和委托類的中介。我們還可以借助代理來在增加一些功能,而不需要修改原有代碼,完美的體現了開閉原則。
真正的業(yè)務功能還是有被代理來實現,但是在實現業(yè)務類之前的一些公共服務,或者之后的服務。我們可以通過代理模式來實現

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 整體Retrofit內容如下: 1、Retrofit解析1之前哨站——理解RESTful 2、Retrofit解析...
    隔壁老李頭閱讀 3,395評論 2 10
  • 一聲驚蟄的雷 帶來了三月的第一場雨 雨淅淅瀝瀝 下了整整一夜 我在陋室一隅 臨窗聽雨 聽花開的聲音 想像草兒努力生...
    風鈴_bb0d閱讀 264評論 0 5
  • 文件包含 兩種方式 cat 作用 查看文件內容 鏈接文件 創(chuàng)建一個多個文件 重定向輸出到終端 重定向到文件 read
    f75dfaf80e43閱讀 1,426評論 0 0
  • 今天下午媽媽帶我去參加入學考試。媽媽想讓我去學奧數。我對媽媽說:“我想去”。媽媽的態(tài)度很堅決,她說:“不想去...
    Cherry多多閱讀 225評論 0 2

友情鏈接更多精彩內容