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

代理模式

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

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

讓4S店幫忙購(gòu)買(mǎi),在從4S那兒買(mǎi)到車(chē)子.

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

應(yīng)用場(chǎng)景

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

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

(一)抽象購(gòu)車(chē)代理接口

public interface Car {
    void buyCar();
}

(二)用戶(hù)實(shí)現(xiàn)購(gòu)車(chē)接口

public class UserBuyCar implements Car {

    private String name;


    @Override
    public void buyCar() {
        System.out.print("\n"+"用戶(hù)買(mǎi)了"+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" + "用戶(hù)什么也沒(méi)買(mǎi)");
        }
    }
}

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

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

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

顯示結(jié)果

用戶(hù)買(mǎi)了audi
用戶(hù)什么也沒(méi)買(mǎi)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  @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)代理類(lè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)代理 買(mǎ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é)果

用戶(hù)買(mǎi)了benz

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

github源碼地址

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

相關(guān)閱讀更多精彩內(nèi)容

  • 整體Retrofit內(nèi)容如下: 1、Retrofit解析1之前哨站——理解RESTful 2、Retrofit解析...
    隔壁老李頭閱讀 3,401評(píng)論 2 10
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類(lèi)相關(guān)的語(yǔ)法,內(nèi)部類(lèi)的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線(xiàn)程的語(yǔ)...
    子非魚(yú)_t_閱讀 34,896評(píng)論 18 399
  • 設(shè)計(jì)模式匯總 一、基礎(chǔ)知識(shí) 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 4,098評(píng)論 1 15
  • Derek:“你們?cè)谶@里干嘛!哈?這是私人領(lǐng)地,私人懂么,不可以隨便進(jìn)入?!?,他微怒的盯著scoot說(shuō)到,而后有輕...
    腿短的痛苦閱讀 861評(píng)論 0 0
  • 貓咪發(fā)情這種事,對(duì)各種寵友來(lái)說(shuō)絕對(duì)不陌生。但如果你以為發(fā)情的貓咪,只是會(huì)變得急躁,并且日日夜夜叫個(gè)不停的話(huà),就大錯(cuò)...
    有寵閱讀 29,596評(píng)論 0 0

友情鏈接更多精彩內(nèi)容