代理模式的动机
在实际的软件系统开发中,经常面临着对一个对象进行访问控制的问题,有些对象不能够直接或者不需要直接被访问。因此就需要一个媒介或者是中间层,来满足调用者和被调用者之间的交互,这时就需要用到代理模式
代理模式的定义
代理模式给某一对象 提供一个代理,并由代理对象来控制对原对象的访问。
例如我需要购买一张火车票,我可以去火车站购买,我也可以去火车站代售处购买,此时这个代售处就相当是一个代理类。并且代售处还可以提供火车站不支持的电话预约服务,但是退票只能去火车站退,代售处不支持退票。说明代理类可以去掉功能服务或者增加额外的功能服务。
代理模式的分类
远程代理:为不同地理的对象,提供局域网代表对象。比如我在北京,上海,广州各有一家连锁店,虽然不可以同时进行实地的考察,但可以坐在电脑面前对我的连锁店进行实时监控。
虚拟代理:根据需要将资源消耗很大的对象进行延迟,用一个相对较小的对象来表示,真实对象真正需要的时候再进行创建。例如我们在浏览一篇新闻的时候,可以先把所有的文字加载出来,图片先用一个类似于占位符的图表示出来,等待真实图片的加载。
保护代理:控制对一个对象的访问权限。给不同的用户提供不同级别的访问权限,比如没有登录的用户只能进行浏览,而登录之后才可以进行评论等操作。
智能引用代理:对一个对象提供一些额外的服务,例如之前说的火车票代售处提供的电话预约功能。
代理模式的实现
静态代理:代理和被代理对象在代理之前是确定的,他们都实现相同的接口或者继承相同的抽象类
public interface Moveable {
void move();
}
public class Car implements Moveable {
@Override
public void move() {
try {
Thread.sleep(new Random().nextInt(1000));//线程休眠0-1000秒
System.out.println("汽车在行驶中");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Car2 extends Car{
public void move(){
long start = System.currentTimeMillis();//获取当前的时间,毫秒
System.out.println("汽车开始行驶");
super.move();
long end = System.currentTimeMillis();
System.out.println("汽车结束行驶");
System.out.println("共行驶了"+(end - start)+"毫秒");
}
}
public class Car3 implements Moveable {
Car car;
Car3(Car car){
this.car = car;
}
public void move(){
long start = System.currentTimeMillis();
System.out.println("汽车开始行驶"+start);
car.move();
long end = System.currentTimeMillis();
System.out.println("汽车结束行驶");
System.out.println("共行驶了"+(end - start)+"毫秒");
}
}
public class Test {
public static void main(String[] args){
Moveable m1 = new Car2();
m1.move();
Car car = new Car();
Moveable m2 = new Car3(car);
m2.move();
动态代理:jdk动态代理
public class TimeHandle implements InvocationHandler {
private Object target;
public TimeHandle(Object target) {
this.target = target;
}
@Override
/**
* proxy:需要代理的类对象
* method:需要代理的方法
* args:方法的参数
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开始行动");
method.invoke(target);
System.out.println("结束行动");
return null;
}
}
public class Test {
public static void main(String[] args){
Car car = new Car();
TimeHandle timeHandle = new TimeHandle(car);
Class clz = car.getClass();
Moveable m = (Moveable)Proxy.newProxyInstance(clz.getClassLoader(),clz.getInterfaces(),timeHandle);
m.move();
}
}