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

2020-10-15  本文已影响0人  Jay_星晨

一、静态代理

代理和被代理对象在代理之前是确定的,他们都实现相同的接口或者继承相同的抽象类。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、返回结果:

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

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

上一篇下一篇

猜你喜欢

热点阅读