1. 程式人生 > >設計模式 --- 代理模式

設計模式 --- 代理模式

1.定義

為其他物件提供一種代理以控制這個物件的訪問。

 

2.使用場景

當無法或不想直接訪問某個物件或訪問某個物件存在困難時,可以時通過一個代理物件來間接訪問,為了保證客戶端使用的透明性,委託物件與代理物件需要實現相同的介面。

 

3.簡單實現

小明通過以法律途徑解決老闆拖欠工資問題,小明需要請一位代理律師來作為自己的代理訴訟人。

靜態代理模式:代理者的程式碼是程式設計師自己或通過自動化工具生成固定的程式碼,再對其進行編譯,就是說在我們的程式碼執行前代理類的class編譯檔案就已經存在。

//定義訴訟類介面
interface ILawsuit{
    //提交申請
    void submit();
    //進行舉證
    void burden();
    //開始辯護
    void defend();
    //完成訴訟
    void finish();
}

//具體訴訟人
class XiaoMin implements ILawsuit{

    @Override
    public void submit() {
        System.out.println("老闆拖欠工作,提起訴訟!");
    }

    @Override
    public void burden() {
        System.out.println("提供合同和工資流水!");
    }

    @Override
    public void defend() {
        System.out.println("證據充分,沒什麼好說的!");
    }

    @Override
    public void finish() {
        System.out.println("訴訟成功,趕緊結算工資!");
    }
}

//代理律師
class Lawyer implements ILawsuit{
    private ILawsuit iLawsuit; //持有一個具體被代理者的引用

    public Lawyer(ILawsuit iLawsuit) {
        this.iLawsuit = iLawsuit;
    }

    @Override
    public void submit() {
        iLawsuit.submit();
    }

    @Override
    public void burden() {
        iLawsuit.burden();
    }

    @Override
    public void defend() {
        iLawsuit.defend();
    }

    @Override
    public void finish() {
        iLawsuit.finish();
    }
}

public class ProxyMode {
    public static void main(String[] args){
        //構造一個小明
        XiaoMin xiaoMin = new XiaoMin();
        //請一個代理律師
        Lawyer lawyer = new Lawyer(xiaoMin);
        //律師提交訴訟
        lawyer.submit();
        //律師進行舉證
        lawyer.burden();
        //律師進行辯護
        lawyer.defend();
        //完成
        lawyer.finish();
    }
}

輸出結果:

 

動態代理模式:通過反射機制動態的生成代理物件,代理誰我們將會在執行階段決定。Java提供了一個動態代理介面InvocationHandler,實現該介面需要重寫呼叫方法invoke。

//建立一個動態代理物件
class DynamicProxy implements InvocationHandler{

    private Object object; //被代理類引用

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

    @Override
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
        //呼叫被代理方法
        Object result = method.invoke(object,objects);
        return result;
    }
}

public class ProxyMode {
    public static void main(String[] args){
        //構造一個小明
        XiaoMin xiaoMin = new XiaoMin();
        //構造動態代理
        DynamicProxy proxy = new DynamicProxy(xiaoMin);
        //獲取被代理類的CLASSLOAD
        ClassLoader loader = xiaoMin.getClass().getClassLoader();
        //動態請一個律師
        ILawsuit lawyer =(ILawsuit) Proxy.newProxyInstance(loader,new Class[]{ILawsuit.class},proxy);
        lawyer.submit();
        lawyer.burden();
        lawyer.defend();
        lawyer.finish();
    }
}

輸出結果和上訴一樣。

 

4.小結

代理模式應用廣泛是一種結構型設計模式,幾乎沒有什麼缺點,要說的話可能就是設計模式的通病,類的增加。