代理模式

代理模式(Proxy Pattern)也稱為委托模式。本質就是為某對象提供一種代理以控制對這個對象的訪問。

場景

很不幸你碰到了一個老板不給你發工資,你會請個律師幫你打官司。很顯然你對打官司一竅不通,因此只能通過代理對象去間接打官司。你作為委托對象,律師作為代理對象,都需要實現相同的接口或繼承相同的抽象類

UML類圖

類圖.png

簡單實現

  1. 訴訟接口類
/**
 * 訴訟接口類
 */
public interface ILawsuit {
    //訴訟方法
    void lawsuit();
}
  1. 訴訟人
/**
 * 訴訟人(委托類)
 */
public class Person implements ILawsuit {
    @Override
    public void lawsuit() {
        System.out.print("我要訴訟");
    }
}
  1. 代理律師
/**
 * 代理律師(代理對象)
 */
public class Laywer implements ILawsuit {
   
    private ILawsuit mLawsuit; //持有被代理者的引用

    public Laywer(ILawsuit lawsuit) {
        this.mLawsuit = lawsuit;
    }

    @Override
    public void lawsuit() {
        mLawsuit.lawsuit();
    }
}
  1. 客戶端調用
public void main(){
    Person mPerson = new Person();
    //構造一個代理律師,并將被代理者作為構造參數傳遞進去
    ILawsuit iLawsuit = new Laywer(mPerson);
    iLawsuit.lawsuit();
}

顯然,一個律師可以幫很多人打官司。其實我們這個代理類可以代理多個訴訟者,只要訴訟實現ILawsuit接口,并將其作為構造參數傳遞進去。

代理模式大致分為兩種:一是靜態代理,二是動態代理。
上述示例即為靜態代理,代碼運行前代理類的class編譯文件已經存在了。而動態代理則相反,它是通過反射機制動態地生成代理對象。Java給我們提供了動態代理接口InvocationHandler,實現此接口需要重寫invoke方法。

延伸

AIDL類圖.png

回想《AIDL淺析》一文中類圖(如上),正是使用了代理模式。

IMyAidlInterface.Stub作為委托類,IMyAidlInterface.Stub.Proxy作為代理類,都實現了IMyAidlInterface接口。而Stub是個抽象類,并不處理過多的具體邏輯,真實的邏輯還是在RemoteService中繼承了IMyAidlInterface.Stub的子類MyBinder里??蛻舳苏{用Stub.asInterface方法將MyBinder對象作為參數傳遞,返回一個AIDL對象,執行add方法。而真實的流程是,asInterface方法首先會在本地查找AIDL對象,如果沒有則實例化Proxy,MyBinder作為參數,執行add方法。顯然Proxy代理了Stubadd方法。

而追溯到底層,就需要了解Binder跨進程通信機制了。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容