Android設(shè)計(jì)模式之(17)----代理模式

代理模式

代理模式屬于結(jié)構(gòu)型模式.分為靜態(tài)代理與動(dòng)態(tài)代理.

比如說 用戶現(xiàn)在要買車,只要一輛車直接去車商買,肯定不會(huì)賣給你啊.這個(gè)時(shí)候用戶就會(huì)找到4S店

讓4S店幫忙購買,在從4S那兒買到車子.

在整個(gè)交易過程中4S的存在就是一個(gè)代理商,用戶作為委托者,代理商幫委托者完成委托者的述求.

應(yīng)用場景

  • 為一個(gè)對象的引用提供額外操作
  • 控制一個(gè)對象的訪問,為不同的用戶提供不同的權(quán)限級別
  • 被訪問對象不想暴露所有細(xì)節(jié)方法,可代理不想暴露的方法
  • 一個(gè)對象不想直接被另一個(gè)對象訪問

代碼示例(靜態(tài)代理)

(一)抽象購車代理接口

public interface Car {
    void buyCar();
}

(二)用戶實(shí)現(xiàn)購車接口

public class UserBuyCar implements Car {

    private String name;


    @Override
    public void buyCar() {
        System.out.print("\n"+"用戶買了"+getName());
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

(三)代理商4S店

public class CarStoreProxy implements Car {
    private UserBuyCar car;

    public CarStoreProxy(UserBuyCar car) {
        this.car = car;
    }

    @Override
    public void buyCar() {
        if (car.getName().equals(ProxyTest.AUDI) ||
                car.getName().equals(ProxyTest.BMW) ||
                car.getName().equals(ProxyTest.BENZ)) {
            car.buyCar();
        } else {
            System.out.print("\n" + "用戶什么也沒買");
        }
    }
}

(四)調(diào)用方式

  //靜態(tài)代理 買奧迪
        UserBuyCar userBuyCar=new UserBuyCar();
        userBuyCar.setName(AUDI);
        CarStoreProxy audiCarStoreProxy=new CarStoreProxy(userBuyCar);
        audiCarStoreProxy.buyCar();

        //靜態(tài)代理 什么也不買
        UserBuyCar userBuyCar1=new UserBuyCar();
        userBuyCar1.setName(NONE);
        CarStoreProxy carStoreProxy=new CarStoreProxy(userBuyCar1);
        carStoreProxy.buyCar();

顯示結(jié)果

用戶買了audi
用戶什么也沒買

以上為用戶買車過程中,4S作為代理商,用戶委托買車的流程案例.實(shí)現(xiàn)類和代理類保證統(tǒng)一性必須都實(shí)現(xiàn)同一個(gè)接口方法.含有具體的代理類.

接口也只能作用于當(dāng)前這個(gè)用戶,如果新添加了方法(租車),所有的實(shí)現(xiàn)類和代理類都需要實(shí)現(xiàn)新方法.

  • 靜態(tài)代理優(yōu)點(diǎn)

    • 使用者只需要關(guān)注用戶業(yè)務(wù)自身的邏輯
  • 靜態(tài)代理缺點(diǎn)

    • 一個(gè)接口只能作用于一個(gè)對象
    • 接口新方法后,所有實(shí)現(xiàn)類 代理類都需要新增方法

代碼示例(動(dòng)態(tài)代理)

在代理模式中的動(dòng)態(tài)代理,不同于靜態(tài)代理含有具體代理類.

動(dòng)態(tài)代理中只要通過反射機(jī)制動(dòng)態(tài)生成代理類,具體代理對象在運(yùn)行時(shí)生成.

Java動(dòng)態(tài)代理Proxy

/獲取指定代理對象所關(guān)聯(lián)的調(diào)用處理器  
static InvocationHandler getInvocationHandler(Object proxy )  

獲取關(guān)聯(lián)于指定類裝載器和一組接口的動(dòng)態(tài)代理類的類對象  
static Class getProxyClass(ClassLoader loader,Class[] interfaces)  

判斷指定類對象是否是一個(gè)動(dòng)態(tài)代理類  
static boolean isProxyClass(Class cl )    

為指定類裝載器君账、一組接口及調(diào)用處理器生成動(dòng)態(tài)代理類實(shí)例
static Object newProxyInstance(ClassLoader loader,  Class[] interfaces, InvocationHandler  h )

newProxyInstance第三個(gè)參數(shù)中的InvocationHandler含有一個(gè)invoke方法,實(shí)現(xiàn)對委托者代理訪問,在每次動(dòng)態(tài)代理都需要通過它指定的調(diào)用器對象.

  @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object result = method.invoke(object,args);
            return result;
    }

實(shí)現(xiàn)InvocationHandler定義動(dòng)態(tài)代理類

public class DynamicProxy implements InvocationHandler {
    private  Object object;

    public DynamicProxy(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object result = method.invoke(object,args);
            return result;
    }
}

調(diào)用方式

        //動(dòng)態(tài)代理 買奔馳
        UserBuyCar userBuyCar2=new UserBuyCar();
        userBuyCar2.setName(BENZ);
        DynamicProxy dynamicProxy=new DynamicProxy(userBuyCar2);
        Car car=(Car) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Car.class},  dynamicProxy);
        car.buyCar();

顯示結(jié)果

用戶買了benz

結(jié)果與靜態(tài)代理效果一致,調(diào)用只需要傳入具體的委托者即可動(dòng)態(tài)生成代理類.相比于靜態(tài)代理更為靈活方便

github源碼地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市输吏,隨后出現(xiàn)的幾起案子物舒,更是在濱河造成了極大的恐慌色洞,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件冠胯,死亡現(xiàn)場離奇詭異火诸,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)荠察,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進(jìn)店門置蜀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人悉盆,你說我怎么就攤上這事盯荤。” “怎么了焕盟?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵秋秤,是天一觀的道長。 經(jīng)常有香客問我,道長灼卢,這世上最難降的妖魔是什么绍哎? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮鞋真,結(jié)果婚禮上蛇摸,老公的妹妹穿的比我還像新娘。我一直安慰自己灿巧,他們只是感情好赶袄,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著抠藕,像睡著了一般饿肺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上盾似,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天敬辣,我揣著相機(jī)與錄音,去河邊找鬼零院。 笑死溉跃,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的告抄。 我是一名探鬼主播撰茎,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼打洼!你這毒婦竟也來了龄糊?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤募疮,失蹤者是張志新(化名)和其女友劉穎炫惩,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體阿浓,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡他嚷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了芭毙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片筋蓖。...
    茶點(diǎn)故事閱讀 38,809評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖稿蹲,靈堂內(nèi)的尸體忽然破棺而出扭勉,到底是詐尸還是另有隱情鹊奖,我是刑警寧澤苛聘,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響设哗,放射性物質(zhì)發(fā)生泄漏唱捣。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一网梢、第九天 我趴在偏房一處隱蔽的房頂上張望震缭。 院中可真熱鬧,春花似錦战虏、人聲如沸拣宰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽巡社。三九已至,卻和暖如春手趣,著一層夾襖步出監(jiān)牢的瞬間晌该,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工绿渣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留朝群,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓中符,卻偏偏與公主長得像姜胖,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子淀散,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評論 2 351

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