设计模式之 代理模式
定义:为其他对象提供一种代理以控制对这个对象的访问。代理对象起到中介作用,可去掉功能服务或增加额外的服务。
代理模式的分类
虚拟代理
远程代理
保护代理
智能引用代理
智能引用代理
静态代理:代理对象和被代理对象在代理之前都是确定的。他们都实现相同的接口或者继承相同的抽象类。
有两种实现方式。
1. 通过继承实现。
2. 通过聚合实现。
情景案例:
我们有一个车类,车具有行驶的方法。通过代理,增加记录行驶时间的方法。
1.定义接口 Moveable.java/*
* 模拟行驶的接口
*/
public interface Moveable {
void move();
}
2.创建一个车类 Car.java 实现这个接口。
public class Car implements Moveable {
public void move() {
//实现开车
try {
Thread.sleep(new Random().nextInt(1000));
System.out.println("汽车行驶中");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
3.现在我们为车类增加一个记录行驶时间的处理,创建一个代理类
用继承的方式实现。public class Car2 extends Car {
public void move() {
long startTime = System.currentTimeMillis();
System.out.println("汽车开始行驶");
super.move();//调用父类的方法,这就实现了Car2 对Car的代理
long endTime = System.currentTimeMillis();
System.out.println("汽车结束行驶,行驶时间:"+(endTime - startTime)+"毫秒");
}
}
用聚合的方式实现
/*
* 使用聚合的方式实现静态代理,聚合就是在一个类中使用到另一个类的对象
*/
public class Car3 implements Moveable {
public Car3(Car car){
super();
this.car = car;
}
private Car car;
public void move() {
long startTime = System.currentTimeMillis();
System.out.println("汽车开始行驶");
car.move();//使用聚合的方式,把参数传进来进行调用
long endTime = System.currentTimeMillis();
System.out.println("汽车结束行驶,行驶时间:"+(endTime - startTime)+"毫秒");
}
}
继承和聚合实现静态代理,那个更合适?
如果我们要在记录行驶时间前增加记录日志功能,则需要创建Car4.java 继承Car2 或者继承Car,如果在增加其他的功能,则代理类就会无限的膨胀,越来越多。所以使用聚合的方式更适合用来实现静态代理。
使用聚合的方式实现静态代理
1.创建日志记录代理类/*
* 使用聚合的方式实现静态代理,聚合就是在一个类中使用到另一个类的对象
* 汽车日志的代理类
*/
public class CarLogProxy implements Moveable {
public CarLogProxy(Moveable moveable){
super();
this.moveable = moveable;
}
private Moveable moveable;
public void move() {
System.out.println("日志开始");
moveable.move();//使用聚合的方式,把参数传进来进行调用
System.out.println("日志结束");
}
}
2.创建行驶时间代理类
/*
* 使用聚合的方式实现静态代理,聚合就是在一个类中使用到另一个类的对象
*/
public class CarTimeProxy implements Moveable {
public CarTimeProxy(Moveable movea