Java設計模式之17 ——代理模式

代理模式也叫委託模式,是一種結構型設計模式。爲其他對象提供一種代理,以控制對這個對象的訪問。那麼什麼時候使用代理模式呢?當無法或者不想直接訪問某個對象時,或者訪問某個對象有困難時,可以通過一個代理對象來間接訪問,爲了保證客戶端使用的透明性,委託對象與代理對象需要實現相同的接口。

 

1 創建一個共同的接口

package proxypattern;

public abstract class Subject {
    /**普通的業務方法*/
    public abstract void visit();
}
 

2 創建一個真實對象的類

package proxypattern;

public class RealSubject extends Subject{

    @Override
    public void visit() {
        //實現具體邏輯
        System.out.println("RealSubject---");
    }
}
 

3 創建一個代理類,在其中聲明真實主題類型的變量

package proxypattern;

public class ProxySubject extends Subject{

    private RealSubject mSubject;
    
    public ProxySubject(RealSubject mSubject) {
        super();
        this.mSubject = mSubject;
    }
    @Override
    public void visit() {
        //通過真實主題引用的對象,調用真實主題中的邏輯方法
        mSubject.visit();
    }
}


4 通過代理類調用真實主題的對象

package proxypattern;

public class Client {

    public static void main(String[] args) {
        //構造真實主題的對象
        RealSubject realSubject = new RealSubject();
        //通過真實主題對象構造一個代理對象
        ProxySubject proxySubject = new ProxySubject(realSubject);
        //調用代理對象的方法,間接調用真實主題的業務邏輯
        proxySubject.visit();
    }
}


輸出結果:RealSubject--Method----

 

以上的代理模式爲靜態代理模式,就是代理類所代理的對象的類型是固定的;此外,我們還可以更加靈活地處理被代理對象的類型,這是動態代理模式:

首先創建一個動態代理類:

package proxypattern;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * 動態代理類
 */
public class DynamicProxy implements InvocationHandler{

    //被代理的類 的引用
    private Object object;
    /**
     * 在構造方法中初始化引用對象
     * @param object
     */
    public DynamicProxy(Object object) {
        this.object = object;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        //調用被代理對象的方法
        Object invoke = method.invoke(object, args);
        return invoke;
    }
}
 

通過Java中的Proxy類,獲取一個RealSubject實現的接口類型一致的代理類,再通過這個代理類調用被代理對象的方法:

package proxypattern;

import java.lang.reflect.Proxy;

public class Test {

    public static void main(String[] args) {
        //1 構造一個被代理對象
        Subject subject = new RealSubject();
        //2 獲取被代理類的ClassLoader
        ClassLoader loader = subject.getClass().getClassLoader();
        //3  構造一個動態代理
        DynamicProxy proxy = new DynamicProxy(subject);
        //4 通過loader構造一個代理對象
        Subject proxyInstance = (Subject) Proxy.newProxyInstance(loader, new Class[]{Subject.class}, proxy);
        //5 代理對象調用被代理對象的方法
        proxyInstance.visit();
    }
}


輸出結果:RealSubject--Method----

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章