• 【设计模式】代理模式


    这就是一个代理模式,让王工改需求,需要联系李总,李总再把工作安排给王工,最终完成了同样的目的,但是有个了中间人。

    同样在Java里的代理模式,也这个道理,客户端不直接访问实际的对象,而是通过中间的代理对象来访问实际对象。

    代理模式分为静态代理和动态代理

    静态代理

    代理和被代理对象在代理之前是确定的。都实现了相同的接口或继承相同的抽象类。举例:

    创建IUser接口

    /**
     * 用户接口
     */
    public interface IUser {
    
        void login();
    } 

    目标对象User:

    /**
     * 实现用户登录,目标对象
     */
    public class User implements IUser {
        @Override
        public void login() {
            System.out.println("用户登录中.....");
        }
    }

    代理对象UserProxy

    /**
     * 代理对象
     */
    public class UserProxy implements IUser {
    
        private IUser target;
    
        public UserProxy(IUser target) {
            this.target = target;
        }
    
        @Override
        public void login() {
            System.out.println("用户开始登录");
            target.login();
            System.out.println("用户结束登录");
        }
    }
     

    测试Run.java

    /**
     * 测试类
     */
    public class Run {
        public static void main(String[] args) {
    
            //目标对象
            User target = new User();
    
            //代理对象,同时把目标对象传给代理对象
            UserProxy userProxy = new UserProxy(target);
            userProxy.login();
    
        }
    }

    运行结果:

    用户开始登录
    用户登录中.....
    用户结束登录

    总结:

    1.静态代理可以代理实现任意接口的目标对象,通用性强。

    2.接口有修改,目标对象和代理对象都要进行修改,增加了维护难度。

    3.代理对象对应着一个目标对象,每个目标对象实现了部分接口,如果目标对象很多,那么静态代理对象也变得臃肿起来。

    为了解决2,3问题,引入动态代理。

    动态代理

    这里介绍使用JDK的代理方式,同样可以代理实现接口的类。

    步骤如下:

    1.编写一个目标类的接口。

    2.实现接口的目标类。

    3.创建一个动态代理类,实现InvocationHandler接口,重写invoke方法。

    举例:步骤1,2使用静态代理的IUser接口和User目标类。

    创建一个动态代理类:

    /**
     * 动态代理类
     */
    public class DynamicProxy implements InvocationHandler {
        private Object target;
    
        public DynamicProxy(Object target) {
            this.target = target;
        }
    
        /**
         * proxy    被代理的对象
         * method   被代理对象的方法
         * args     方法的参数
         * return   Object方法的返回值
         */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("开始登录");
            //执行目标类方法
            Object result = method.invoke(target, args);
            System.out.println("结束登录");
            return result;
        }
    }
     

    测试类:Run2.java

    /**
     * 测试类
     */
    public class Run2 {
    
        public static void main(String[] args) {
    
            //目标对象
            User target = new User();
    
            //代理对象,同时把目标对象传给代理对象
            DynamicProxy dynamicProxy = new DynamicProxy(target);
    
            //给目标生产代理对象
            /**
             * loader      类加载器
             * interfaces  实现接口
             * h           InvocationHandle
             */
            IUser iUser = (IUser) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), dynamicProxy);
            iUser.login();
        }
    }

    运行结果:

    用户开始登录
    用户登录中.....
    用户结束登录

  • 相关阅读:
    ssh整合
    自定义Java集合
    java图形界面写个小桌面,内置简单小软件
    java简单日历
    javaSwing
    javaScript封装
    java解析xml文件
    缺省适配器
    适配器模式
    自定义SWT控件一之自定义单选下拉框
  • 原文地址:https://www.cnblogs.com/woniu201/p/10641476.html
Copyright © 2020-2023  润新知