也說說代理模式

  
代理模式:就是爲了分離出業務層而採取的一種模式,比如說在一個邏輯中,要記錄邏輯執行前後的日誌,那麼通常我們的方法是這樣的
    方法名(){
        記錄日誌
        邏輯代碼
        記錄日誌
}
當邏輯代碼和日誌代碼寫到一起的時候,我們就會發現這個方法中包含了太多的東西,顯得有些混亂,解決這種情況我們可以採取代理模式。
 
靜態代理模式:
採取靜態代理模式我們需要一個公共接口,同過實現此接口來生成代理類和業務類
比如:
package staticProxy;
 
/**
 *接口
 *@authorDavid.Qiu
 *
 */
publicinterface IOperate {
    publicvoid doExcute();
}
 
在這個接口中,我們有一個doExcute方法,這個方法將在繼承此接口的類中執行業務邏輯
下面我們生成一個業務類
package staticProxy;
 
/**
 * 真實角色
 * @author David.Qiu
 *
 */
public class RealOperate implements IOperate {
 
    public RealOperate() {
        // TODO Auto-generated constructor stub
    }
 
    public void doExcute() {
        // TODO Auto-generated method stub
        System.out.println("Real Class is doing something!");
    }
 
}
 
在這個類中,我們實現了接口中的方法,並且只讓他執行業務,打印出字符串。
 
之後我們需要生成一個代理類來代理執行業務邏輯
package staticProxy;
 
/**
 * 代理角色
 * @author David.Qiu
 *
 */
public class ProxyOperate implements IOperate {
 
    //private RealOperate realOperate;
   
    private IOperate realOperate;
   
    public ProxyOperate(IOperate realOperate) {
        // TODO Auto-generated constructor stub
        this.realOperate=realOperate;
    }
   
    public void doExcute() {
        // TODO Auto-generated method stub
        start();
        /**
        if(realOperate==null){
            realOperate=new RealOperate();
        }
        */
        realOperate.doExcute();
        end();
    }
   
    /**
     * start
     */
    public void start(){
        System.out.println("start...");
    }
    /**
     * end
     */
    public void end(){
        System.out.println("end...");
    }
 
}
 
在這個代理類中,我們照樣實現了接口中的方法,只不過在這一次我們在方法中加入了日誌記錄操作,並且通過調用業務類來實現業務邏輯,這樣,我們就可以把業務邏輯和日誌記錄分開了。
當我們的業務邏輯改變時,只需要修改RealOperate中的doExcute方法就可以了,這樣可以讓程序看起來耦合度比較低。
測試一下:
package staticProxy;
 
/**
 * 測試類
 * @author David.Qiu
 *
 */
public class TestMain {
 
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        IOperate proxyOperate=new ProxyOperate(new RealOperate());
        proxyOperate.doExcute();
    }
 
}
當然,上面所說的是靜態代理方法,只是個代理模式的原理,如果真正使用的話我們最好使用動態代理,所以下面我們來看一下動態代理
動態代理:
當然,接口還是需要的
package dynamicProxy;
 
publicinterface IOperate {
    publicvoid doExecute();
}
生成業務類
package dynamicProxy;
 
public class RealOperate implements IOperate {
 
    public void doExecute() {
        // TODO Auto-generated method stub
        System.out.println("Real Class is doing something!");
    }
}
重點我們看下代理類,它需要實現一個接口java.lang.reflect.InvocationHandler
,該接口中有個方法Object invoke(Object proxy, Method method,Object[] args)
              throws Throwable
package dynamicProxy;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
 
publicclass ProxyOperate implements InvocationHandler {
   
    private Object object;
   
    public Object bind(Object object){
        this.object=object;
       return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), this);
    }
 
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("Start...");
        method.invoke(this.object, null);
        System.out.println("End...");
        returnnull;
    }
}
測試一下
package dynamicProxy;
 
publicclass TestMain {
 
    /**
     *@paramargs
     */
    publicstaticvoid main(String[] args) {
        // TODO Auto-generated method stub
        ProxyOperate proxy=new ProxyOperate();
        IOperate operate=(IOperate) proxy.bind(new RealOperate());
        operate.doExecute();
    }
}
從這兩個例子中可以看出代理模式在保持系統的低耦合方面是個不錯的選擇,Spring框架中的AOP就是根據代理模式得來的,AOP的一些東西我將會在下一片文章中介紹。
發佈了39 篇原創文章 · 獲贊 3 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章