1. 程式人生 > 其它 >2.2 工廠模式、動態代理

2.2 工廠模式、動態代理

1、工廠模式

定義:專門定義一個類用於建立其它類的例項(物件)

作用:解決類與類之間的耦合問題,遮蔽了外界對具體類的依賴

工廠模式實現步驟:

  1. 編寫一個Car介面,提供run方法
  2. 編寫一個Benz類,實現Car介面、run方法
  3. 編寫一個BMW類,實現Car介面、run方法
  4. 提供一個CarFactory(汽車工廠類),用於生產汽車例項
// 汽車工廠類
public class CarFactory {
    public static Car newCar(int carType) {
        if (carType == 1) 
            return new Benz();
        else
            return new BMW();
    }
}

 

2、動態註解(難點)

動態代理

/*
動態代理:

動態代理的作用: 增強某一個物件的某些方法。

動態代理模式的涉及角色:
    1. 被代理物件
    2  代理物件
    3. 介面(代理物件能夠代理的方法)

需求:編寫動態代理物件增強Arraylist的add方法,新增成功或者新增失敗都通知一下使用者


動態代理涉及到類:
    Proxy

 涉及到的方法:
    newProxyInstance(ClassLoader loader, Class<?>[] interfaces,  InvocationHandler h)   生成指定介面的代理物件。
        loader: 類載入器 ,這個引數直接使用使用當前類的載入器,不需要管它
        interfaces: 生成代理物件實現的介面
        InvocationHandler: 處理器

第一個疑問:invoke方法什麼時候會執行?
    呼叫代理的物件任何一個方法都會執行invoke一次。

第二個疑問: 每調一次代理物件的方法就執行一次invoke方法的目的是什麼呢?
    讓你自己實現每一個方法的編寫。因為它本身不懂如何實現、增強這個方法


 動態代理的固定的步驟:
    1. 維護一個被代理物件, 在被代理物件的基礎去增強
    2. 獲取當前執行的方法名.
    3. 判斷是否是需要被增強的方法,如果是需要增強方法,讓被代理執行當前方法,然後寫上自己增強的邏輯
    4. 如果不是需要增強方法, 讓被代理執行當前方法
    5. 方法執行的時候不管方法是否需要有返回值都使用變數去接收,然後返回即可。

 */
public class Demo1 {

    /*
        這個方法的作用生成list介面代理物件
     */
    public static List getListProxy(){
        List listProxy = (List) Proxy.newProxyInstance(Demo1.class.getClassLoader(),
                new Class[]{List.class}, new InvocationHandler() {


            //3. 維護一個被代理物件
            List list = new ArrayList();

            /*
                proxy: 當前的代理物件,不需要管
                Method: 當前代理物件執行方法
                args: 執行當前方法傳遞的引數
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //1. 獲取當前執行方法名
                String methodName = method.getName();
                //2. 判斷方法是否為需要增強的方法

                //定義一個變數接收方法返回值
                Object result = null;
                if("add".equals(methodName)){
                    //是需要增強的方法,讓被代理物件執行當前方法,然後你在這基礎上再新增自己的增強邏輯
                    result = method.invoke(list,args);
                    // 增強的邏輯
                    if((boolean)result){
                        System.out.println("新增"+args[0]+"成功");
                    }else{
                        System.out.println("新增"+args[0]+"失敗");
                    }


                }else{
                    //不需要增強的方法,則使用被代理物件直接執行即可。
                    result = method.invoke(list,args); // obj 方法呼叫者物件  args方法所需要的引數
                }

                return result;
            }
        });
        return listProxy;
    }



    public static void main(String[] args) {
        List listProxy = getListProxy(); //擁有List介面中的所有方法
        listProxy.add("冰冰");
        listProxy.add("美美");
        listProxy.add("獸獸");

        System.out.println("集合:"+listProxy);


    }
}
/*
新增冰冰成功
新增美美成功
新增獸獸成功
集合:[冰冰, 美美, 獸獸]
*/

 

 

 

-end