1. 程式人生 > >筆記14:設計模式之動態代理

筆記14:設計模式之動態代理

代理模式

* 概念:
	1. 真實物件:被代理的物件
	2. 代理物件:
	3. 代理模式:代理物件代理真實物件,達到增強真實物件功能的目的

* 實現方式:
	1. 靜態代理:有一個類檔案描述代理模式
	2. 動態代理:在記憶體中形成代理類
		* 實現步驟:
			1. 代理物件和真實物件實現相同的介面
			2. 代理物件 = Proxy.newProxyInstance();
			3. 使用代理物件呼叫方法。
			4. 增強方法

		* 增強方式:
			1. 增強引數列表
			2. 增強返回值型別
			3. 增強方法體執行邏輯

動態代理程式碼演示 1.共同的介面

public interface SaleComputer {

    public String sale(double money);

    public void show();

}

2.真實類

/**
 * 真實類
 */
public class Lenovo implements SaleComputer {
    @Override
    public String sale(double money) {

        System.out.println("花了"+money+"錢買了一臺聯想電腦");

        return "聯想電腦";
    }

    @Override
    public void show() {
        System.out.println("展示電腦...");
    }
}

3.代理類

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

public class ProxyTest {

    public static void main(String[] args) {

        //1.建立真實物件
        Lenovo lenovo = new Lenovo();

        //動態代理增強lenovo方法
        /*該方法的三個引數:
              * 1.類載入器: 真實物件.getClass().getClassLoader()
              * 2.介面陣列: 真實物件.getClass().getInterfaces()
              * 3.處理器: new InvocationHandler() {} -->編寫代理的邏輯
        */
		//Proxy.newProxyInstance()方法返回的是一個代理物件,可以將這個代理物件轉成介面物件
        SaleComputer proxy_lenovo = (SaleComputer) Proxy.newProxyInstance(lenovo.getClass().getClassLoader(), lenovo.getClass().getInterfaces(), new InvocationHandler() {

            //代理邏輯編寫的方法,代理物件呼叫的所有方法都會觸發該方法的執行

            /*該方法的三個引數:
             * 1.proxy : 代理物件
             * 2.method : 該方法會將代理物件呼叫的方法封裝成為一個物件,method就是那個封裝後的物件
             * 3.args : 代理物件呼叫方法時,實際傳遞的引數
             */

            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

               /* System.out.println("該方法執行了...");
                System.out.println(method.getName());
                System.out.println(args[0]);*/

               //判斷是否是sale方法--是sale方法才增強
                if (method.getName().equals("sale")) {
                    //增強引數
                    double money = (double) args[0];
                    money = money * 0.85;

                    System.out.println("專車接駕...");//增強方法體的邏輯

                    //使用真實物件呼叫該方法--代理物件本身是無法呼叫真實物件的方法的,真實物件呼叫方法然後將結果交給代理物件
                    Object obj = method.invoke(lenovo, money);

                    System.out.println("免費送貨到家...");//增強方法體的邏輯

                    //增強返回值
                    return obj + "_滑鼠墊";
                } else {//不是sale方法就原樣執行(該咋執行咋執行)
                    Object obj = method.invoke(lenovo, args);
                    return obj;
                }
            }
        });

        //2.使用代理物件呼叫方法
        String computer = proxy_lenovo.sale(8000);
        System.out.println(computer);

        //lenovo.show();
		//proxy_lenovo.show();
    }
}