使用代理模式可以在不改变源码的情况下来给源码增加一些额外的功能,这种模式叫做AOP面向切面编程。
1.举一个例子
买火车票可以直接去火车站也可以去火车票代售处 火车票代售处可能会提供一些额外的服务,比如收手续费,不支持退票
代理对象起到中介的作用,可以去掉功能服务或者增加额外的服务
2.代理模式可以分为
远程代理:如客户端服务器模式
虚拟代理:如图片加载消耗较大,可以用一张图片代替这张图片,等待图片加载完成再显示
保护代理:权限问控制,登录可以发帖,不登录就不可以
智能引用代理:例如火车票代售处,可以提供一些额外的服务
3.静态代理及其实现
静态代理:代理和被代理对象在代理之前是确定的,他们都实现相同的接口或者继承相同的抽象类
例如:一辆车,有行驶的方法,通过代理,增加额外的方法记录行驶时间
接口类
public interface ICar {
public void move();
}
被代理类
ublic class Car1 implements ICar{
@Override
public void move() {
System.out.println("开始行驶");
System.out.println("正在行驶");
}
(1)通过继承的方式实现静态代理:
子类继承父类,在父类方法前后增加想要添加的业务逻辑即可!
public class Car2 extends Car1 {
@Override
public void move() {
// TODO Auto-generated method stub
super.move();
System.out.println("汽车行驶时间");//增加了记录汽车行驶时间的功能
}
}
(2)通过聚合方式实现静态代理,两个实现类实现相同的接口,代理类中以被代理类作为参数
public class Car3 implements ICar {
//引入被代理的类
private Car1 car1;
//将被代理的类作为构造方法的参数
public Car3(Car1 car1) {
this.car1 = car1;
}
@Override
public void move() {
car1.move();
//添加额外的方法
System.out.println("汽车行驶时间");
}
}
两种方式的优劣分析:
使用继承:若要再添加新的打印日志的功能,需要再次创建新的代理类,若要添加新的先打印日志在输出时间的功能,还要添加新的代理类
使用聚合:若要再添加新的打印日志的功能,需要再次创建新的代理类,若要添加新的先打印日志在输出时间的功能,则无需创建新的类,只要改变一下传递的参数就可以了
首先将car3中的参数改为接口类ICar
public class Car3 implements ICar {
//引入被代理的类
private ICar iCar;
//将被代理的类作为构造方法的参数
public Car3(ICar iCar) {
this.iCar = iCar;
}
@Override
public void move() {
iCar.move();
//添加额外的方法
System.out.println("汽车行驶时间");
}
}
car4代码
public class Car4 implements ICar{
private ICar iCar;
//将被代理的类作为构造方法的参数
public Car4(ICar iCar) {
this.iCar = iCar;
}
@Override
public void move() {
iCar.move();
//添加额外的方法
System.out.println("打印日志");
}
}
测试类
public class TestProxy {
public static void main(String[] args) {
Car1 car1 = new Car1();
// Car3 car3 = new Car3(car1);
// Car4 car4 = new Car4(car3);
// car4.move();
//若要改变方法的先后顺序,只需要改变调用的先后顺序即可
Car4 car4 = new Car4(car1);
Car3 car3 = new Car3(car4);
car3.move();
}