• 模式的秘密-代理模式(1)-静态代理


    代理模式:

    为其他对象提供一种代理以控制对这个对象的访问,代理对象起到了中介作用,可以去掉功能服务或者额外的服务。

    以火车站买票为例子:

    火车票代售处是火车站的代理,代售处可能不止可以卖火车票,还可以卖飞机票,但是不支持火车票退票功能,因此代售处起到了中介作用,

    可以去掉功能服务或者额外的服务。

    常见代理模式:远程代理,虚拟代理,保护代理,智能引用代理。

    智能引用代理

    两种实现方式:静态代理,动态代理。

    静态代理:代理和被代理对象在代理之前是确定的。他们都实现相同的接口或者继承相同的抽象类。

    静态代理分继承方式和聚合方式两种实现

    实例:

    通过代理,实现汽车行驶的方法,同时记录汽车的行驶时间。

    普通不使用设计模式实现方式

    第一步:行驶接口:

    package com.Proxy;
    
    public interface Moveable {
        
        void move();
    
    }

    第二步:实现汽车类:汽车类中实现行驶方法,里面记录行驶时间。

    package com.Proxy;
    
    import java.util.Random;
    
    public class Car implements Moveable {
    
        @Override
        public void move()
        {
            long starttime=System.currentTimeMillis();
            System.out.println("汽车开始形式....");
            //实现开车
            try {
                Thread.sleep(new Random().nextInt(1000));
                System.out.println("汽车行驶中....");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
            long endtime=System.currentTimeMillis();
            System.out.println("汽车结束行驶...汽车形式时间:"+(endtime-starttime)+"毫秒");
        }
    
    }

    第三步:测试:

    package com.Proxy;
    
    public class Client {
    
        /*
         * 测试类
         * */
        public static void main(String[] args) {
    
            Car car=new Car();
            car.move();
        }
    
    }

    运行结果:

    汽车开始形式....
    汽车行驶中....
    汽车结束行驶...汽车形式时间:602毫秒

    修改为静态代理:

    第一种静态代理:以继承的方式代理:

    Car类修改为只有行驶方式:

    package com.Proxy;
    
    import java.util.Random;
    
    public class Car implements Moveable {
    
        @Override
        public void move()
        {
    
            //实现开车
            try {
                Thread.sleep(new Random().nextInt(1000));
                System.out.println("汽车行驶中....");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    新建Car2类继承Car类,通过super.方法()方式调用父类的方法,实现静态代理。

    同时在这个方法里面实现记录开车时间。

    package com.Proxy;
    
    public class Car2 extends Car {
    
        @Override
        public void move() {
            
            long starttime=System.currentTimeMillis();
            System.out.println("汽车开始形式....");
            super.move();
            long endtime=System.currentTimeMillis();
            System.out.println("汽车结束行驶...汽车形式时间:"+(endtime-starttime)+"毫秒");
        }
    }

    测试:

    package com.Proxy;
    
    public class Client {
    
        /*
         * 测试类
         * */
        public static void main(String[] args) {
    
            Moveable m=new Car2();
            m.move();
        }
    }

    效果:

    汽车开始形式....
    汽车行驶中....
    汽车结束行驶...汽车形式时间:497毫秒

    第二种静态代理:以聚合的方式实现代理:

    聚合的方式其实就是在一个类中调用另一个类的对象,一般在构造方法里面把另一个类的对象传进来。

    实现:

    Car类和接口同上。

    新建Car3继承接口,同时在构造方法里面把Car类对象传进来。

    package com.Proxy;
    
    /*
     * 以聚合方式代理:一个类中调用另一个类的对象
     * */
    
    public class Car3 implements Moveable{
    
        private Car car;
        
        public Car3(Car car)
        {
            this.car=car;
        }
        
        @Override
        public void move()
        {
            long starttime=System.currentTimeMillis();
            System.out.println("汽车开始形式....");
            car.move();
            long endtime=System.currentTimeMillis();
            System.out.println("汽车结束行驶...汽车形式时间:"+(endtime-starttime)+"毫秒");
        }
    }

    测试:

    package com.Proxy;
    
    public class Client {
    
        /*
         * 测试类
         * */
        public static void main(String[] args) {
    //        不使用代理方式
    //        Car car=new Car();
    //        car.move();
            
    //        //以继承方式实现代理
    //        Moveable m=new Car2();
    //        m.move();
            
            //以聚合方式实现代理
            Car car=new Car();
            Moveable m2=new Car3(car);
            m2.move();   
        }
    }

    效果:

    汽车开始形式....
    汽车行驶中....
    汽车结束行驶...汽车形式时间:200毫秒

    继承方式和聚合方式两种比较:

    如果此时代理类除了要实现汽车行驶方法,还可能需要实现其他功能的代理,比如权限管理,日志处理。

    1,对于继承方式的代理来说:

    如果我想先记录汽车行驶时间,在记录日志,需要新建一个代理类。

    假如此时我又想先记录日志,再记录汽车行驶时间,此时又得新建一个代理类。

    所以使用继承方式不合适。

    2,使用聚合方式就没这个问题,代码验证:

    这里要实现两种方式:即先记录时间,再记录日志;和先记录日志,再记录时间。

    实现的方式就是,各个功能分别建立一个代理类,并且代理类的构造方法不仅能够传递被代理类(Car),也能能够把其他的代理类传递进来,

    以此实现上述的两种不同的实现方式

    代码:

    新建一个时间记录代理类:

    为了可以让构造方法里面的参数既可以是被代理的Car类,也可以是代理类。

    package com.Proxy;
    
    //时间代理
    public class CarTimeProxy implements Moveable{
    
        private Moveable m;
        
        public CarTimeProxy(Moveable m)
        {
            this.m=m;
        }
        
        @Override
        public void move()
        {
            long starttime=System.currentTimeMillis();
            System.out.println("汽车开始形式....");
            m.move();
            long endtime=System.currentTimeMillis();
            System.out.println("汽车结束行驶...汽车形式时间:"+(endtime-starttime)+"毫秒");
        }
    }

    新建一个日志记录代理类:

    package com.Proxy;
    
    //日志代理
    public class CarLogProxy implements Moveable{
    
        private Moveable m;
        
        public CarLogProxy(Moveable m)
        {
            this.m=m;
        }
        
        @Override
        public void move()
        {
            System.out.println("日志开始....");
            m.move();
            System.out.println("日志结束....");
        }
    }

    新建测试类:测试类分别通过两个代理类顺序不同,把相关代理类传递给另一个代理类调用:

    package com.Proxy;
    
    //聚合的代理模式,各个代理类直接可以互相传递,组合,
    public class Clien2 {
    
        public static void main(String[] args) {
    
            Car car=new Car();
    //        //先记录日志,再记录时间
    //        CarTimeProxy ctp=new CarTimeProxy(car);
    //        CarLogProxy clp=new CarLogProxy(ctp);//把时间代理传进去,这时候日志代理类代理了时间代理类
    //        clp.move();
    
            //先记录日志,再记录日志,只需要调整一下代理类的顺序
            CarLogProxy clp2=new CarLogProxy(car);
            CarTimeProxy ctp2=new CarTimeProxy(clp2);//把时间代理传进去,这时候日志代理类代理了时间代理类
            ctp2.move();
            
        }
    }
  • 相关阅读:
    jQuery火箭图标返回顶部代码
    易购商城首页
    使用HTML5验证博客园用户注册页面
    正则表达式相关内容和用法
    表单
    jQuery制作图片提示效果
    jQuery遍历
    用js制作论坛发贴
    使用jQuery操作DOM
    京东常见问题分类页面
  • 原文地址:https://www.cnblogs.com/alsf/p/8506866.html
Copyright © 2020-2023  润新知