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

相关