美文网首页
设计模式-代理模式(静态代理)

设计模式-代理模式(静态代理)

作者: Jay_星晨 | 来源:发表于2020-10-15 00:50 被阅读0次

    一、静态代理

    代理和被代理对象在代理之前是确定的,他们都实现相同的接口或者继承相同的抽象类。UML模型如下: 6632620276117148876.jpg

    下面分别通过继承和聚合的方式实现静态代理。

    二、继承方式实现静态代理

    1、创建一个接口

    public interface Moveable {
        void move();
    }
    

    2、创建一个Car类

    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) + " 秒");
        }
    }
    

    3、通过继承的代理方式来实现记录汽车行驶时间,新建Car2类,继承Car类。此时注释掉Car类中的行驶起止时间。

    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类如下定义:

    public class Car2 extends Car {
        public Car2() {
            super();
        }
        @Override
        public void move() {
            long startTime=System.currentTimeMillis();
            System.out.println("汽车开始行驶。。。");
            super.move();
            long endTime=System.currentTimeMillis();
            System.out.println("汽车结束行驶。。。行驶时间 " + (endTime - startTime) + " 秒");
        }
    }
    

    测试类:

    public class ProxyTest {
        public static void main(String[] args) {
            Moveable moveable=new Car2();
            moveable.move();
        }
    }
    

    输出结果:

    汽车开始行驶。。。
    汽车行驶中。。。
    汽车结束行驶。。。行驶时间 968 秒
    

    三、聚合方式实现静态代理

    聚合概念:一个类中会调用另一个对象。
    1、创建一个Car3类,实现Moveable接口。

    public class Car3 implements Moveable {
        private Car car;
        public Car3(Car car) {
            super();
            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) + " 秒");
        }
    }
    

    2、测试类:

    public class ProxyTest {
        public static void main(String[] args) {
            Car car=new Car();
            Moveable moveable=new Car3(car);
            moveable.move();
        }
    }
    

    3、输出结果:

    汽车开始行驶。。。
    汽车行驶中。。。
    汽车结束行驶。。。行驶时间 10 秒
    

    四、继承方式实现代理的优缺点

    如果要叠加业务,比如说要加权限的处理,加日志的处理。则需定义新的子类,继承Car2或者Car3,在move方法进行权限或日志的处理。根据叠加业务及处理顺序不同,分别要创建不同的子类,这样子类会无限膨胀下去,不好管理。但是聚合可以避免这个问题。

    五、聚合的优势体现

    需求:叠加对日志的处理及日志的处理
    1、新建日志代理类,实现Moveable接口:

    public class CarLogProxy implements Moveable {
        private Moveable m;
        public CarLogProxy(Moveable m) {
            super();
            this.m=m;
        }
        @Override
        public void move() {
            System.out.println("日志开始。。。");
            m.move();
            System.out.println("日志结束。。。");
        }
    }
    

    2、新建时间代理类,实现Moveable接口:

    public class CarTimeProxy implements Moveable {
        private Moveable m;    
        public CarTimeProxy(Moveable m) {
            super();
            this.m=m;
        }
        @Override
        public void move() {
            System.out.println("汽车开始行驶。。。");
            m.move();
            System.out.println("汽车结束行驶。。。");
        }
    }
    

    3、Car类

    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();
            }
        }
    }
    

    4、测试类:

    public class Test {
        public static void main(String[] args) {
            Car car=new Car();
            CarLogProxy carLogProxy=new CarLogProxy(car);
            CarTimeProxy carTimeProxy=new CarTimeProxy(carLogProxy);
            carTimeProxy.move();
        }
    }
    

    5、输出结果:

    汽车开始行驶。。。
    日志开始。。。
    汽车行驶中。。。
    日志结束。。。
    汽车结束行驶。。。
    

    6、改变代理顺序进行测试:

    public class Test {
        public static void main(String[] args) {
            Car car=new Car();
            CarTimeProxy carTimeProxy=new CarTimeProxy(car);
            CarLogProxy carLogProxy=new CarLogProxy(carTimeProxy);
            carLogProxy.move();
        }
    }
    

    7、返回结果:

    日志开始。。。
    汽车开始行驶。。。
    汽车行驶中。。。
    汽车结束行驶。。。
    日志结束。。。
    

    很显然,聚合实现代理方式比继承代理方式更为灵活,代理之间可以互相组合,互相传递。
    但是又问题来了,如果要实现火车,自行车对时间的代理呢,则又需要创建火车的时间代理类,自行车的时间代理类。火车的日志代理类,自行车的日志代理类,代理类仍然会膨胀下去。可以通过动态代理来解决这个问题。

    相关文章

      网友评论

          本文标题:设计模式-代理模式(静态代理)

          本文链接:https://www.haomeiwen.com/subject/zkzgpktx.html