zoukankan      html  css  js  c++  java
  • 代理模式

    11、代理

    场景:

    1、租房:包括房东(真实对象),中介(代理对象),客户(被代理对象)

    • 房东:想要租房,只想租房,不想管带看房、签合同等操作。

      • 租房接口:里面包含租房方法【因为不可能只有你一个人要租房】
      • 房东类:里面实现了租房接口
    • 中介:此时出现了中介,中介帮房东租房,包括带看房、签合同、以及获取自己的中间费用

      • 中介类:同样实现租房接口,但是里面实现的方法是set房东类完成的,其他操作中介类自行添加
    • 客户:客户不用去找房东,直接找中介,中介带你做你所需要的任何操作。

      • 客户类:只需要new 中介类,就可以完成租房或者其他一系列操作

    静态代理

    实例测试静态代理模式

    Why?

    • UserDaoImpl实现了UserDao接口;
    • 现有新的需求,要在每个实现的方法前添加日志
    • 一般不能修改原有的代码,所以使用一个代理类,将所需要的一些代码切入进去
    • 用户访问的时候,就直接访问代理类
    • 代理类同样需要实现接口

    UserDao

    public interface UserDao {
    
        //增
        int add();
    
        //删
        int delete();
    
        //查
        List<User> select();
    
        //改
        int update();
    
    }
    

    UserDaoImpl

    public class UserDaoImpl implements UserDao {
        @Override
        public int add() {
            System.out.println("增");
            return 0;
        }
    
        @Override
        public int delete() {
            System.out.println("删");
            return 0;
        }
    
        @Override
        public List<User> select() {
            System.out.println("查");
            return null;
        }
    
        @Override
        public int update() {
            System.out.println("改");
            return 0;
        }
    }
    

    StaticProxy

    public class StaticProxy implements UserDao {
    
        private UserDao userDao;
    
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
    
        @Override
        public int add() {
            log("正在执行增加操作");
            userDao.add();
            return 0;
        }
    
        @Override
        public int delete() {
            log("正在执行删除操作");
            userDao.delete();
            return 0;
        }
    
        @Override
        public List<User> select() {
            log("正在执行查询操作");
            userDao.select();
            return null;
        }
    
        @Override
        public int update() {
            log("正在执行修改操作");
            userDao.update();
            return 0;
        }
    
        //需求:切入一段日志
        private static void log(String msg){
            System.out.println("[DEBUG]"+msg);
        }
    
        public void myMethod(){
            System.out.println("这是我代理类特有的方法");
        }
    }
    

    Test

    @Test
    public void test(){
        //真实对象需要做的事情
        UserDao userDao = new UserDaoImpl();
    
        //需要一个代理对象
        StaticProxy proxy = new StaticProxy();
    
        //代理对象去代理真实类【set方法】
        proxy.setUserDao(userDao);
    
        //执行被代理对象需要执行的操作
        proxy.add();
    
        //代理对象还可以自己做一些额外的操作
        proxy.myMethod();
    }
    

    好处:

    不用修改自身原来的代码而动态实现代码的切入;

    真实对象只需负责主要的业务,不用关心一些公共的业务,实现的业务的分工。

    坏处:

    静态代理一个真实对象就会产生一个代理对象,代码量增加,效率变低。

    动态代理

    动态代理的方式:

    1. 基于接口:JDK动态代理
    2. 基于类:cglib
    3. java字节码:javassist

    动态代理需要了解2个类:

    • Proxy:生成代理对象
    • InvocationHandler:代理对象处理程序
      • 实现该类,来创建代理对象和通过反射机制执行代理对象所要执行的操作

    DynamicProxy

    /**
     * 动态代理的实现
     */
    //用来创建代理对象,并执行代理程序
    public class DynamicProxy implements InvocationHandler {
    
        //代理类所需要代理的真实对象
        private Object object;
    
        public void setObject(Object object) {
            this.object = object;
        }
    
        //获取代理对象
        public Object getProxy(){
            /**
             * 参数一:生成代理对象的类加载器
             * 参数二:代理类所要代理的接口
             * 参数三:指实现InvocationHandler的类
             */
            return Proxy.newProxyInstance(this.getClass().getClassLoader(),object.getClass().getInterfaces(),this);
        }
    
    
        //代理对象处理方法
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            //使用代理类method去执行,参数一指的就是所需要代理的真实对象
            Object invoke = method.invoke(object, args);
            return invoke;
        }
    }
    

    Test

    @Test
    public void test1(){
        //真实对象所需要执行的操作
        UserDao user = new UserDaoImpl();
    
        //创建代理对象处理程序
        DynamicProxy proxy = new DynamicProxy();
    
        //设置所要代理的真实对象
        proxy.setObject(user);
    
        //创建代理对象
        UserDao proxy1 = (UserDao) proxy.getProxy();
    
        //执行
        proxy1.add();
    
    }
    

    总结:静态代理和动态代理的区别?

    静态代理:

    ​ 一个类只能创建一个代理对象;

    ​ 代理对象需要程序员自己手动创建;

    动态代理

    ​ 可研通过JDK原生接口,或者cglib包动态为所有类创建代理对象;

    ​ 是动态创建的,不用自己手动创建;

  • 相关阅读:
    使用DataList进行ItemDataBound时出来重复绑定
    往一个数据添加另外一个数据表里面的数据
    在ServU配置ODBC过程记录(一)
    在RowDeleting中GridViewDeleteEventArgs e的RowIndex获得值错误的问题
    在Master母版页中通过FindControl()方法获取服务器控件
    经典的间隔时间滚动新闻(图片),可控制滚动
    为枚举类型添加描述信息 this 扩展 泛型约束 位运算[转]
    SQL Server 获取插入记录后的ID(自动编号)
    Shapes
    CSSFriendlyAdapter 的一个Bug
  • 原文地址:https://www.cnblogs.com/IT_CH/p/13506866.html
Copyright © 2011-2022 走看看