目录
一、代理模式引出
首先我们来看一段案例代码:
这是我们需要进行操作的实体类。
public class Tank {
public void move() throws Exception {
System.out.println("Tank is repairing...");
Thread.sleep(3000);
System.out.println("Tank is moving, calcalcal...");
}
}
下面我们有个需求,就是要获得Tank实体类move启动的时间,可能有些小伙伴会想到通过继承来实现:
public class Main {
public static void main(String[] args) throws Exception {
TankEditor tankEditor = new TankEditor();
tankEditor.move();
}
}
class TankEditor extends Tank{
@Override
public void move() throws Exception {
long start = System.currentTimeMillis();
super.move();
long end = System.currentTimeMillis();
System.out.println("坦克启动时间"+(end-start)+"ms");
}
}
运行结果:可以看到这种方式可以实现该需求的,但如果我们需要再添加相应的操作时,该方式就会显得耦合度过高了,使用此种方式我们需要不停的继承要代理的对象,并不适合拓展。
于是引出我们的代理设计模式
为引出最终的代理模式,我们先来看一下改进为聚合模式来实现的效果:
public class Main {
public static void main(String[] args) throws Exception {
Moveable moveable=new TankEditor(new Tank());
moveable.move();
}
}
class TankEditor implements Moveable{
Tank tank;
public TankEditor(Tank tank) {
this.tank = tank;
}
@Override
public void move() throws Exception {
long start=System.currentTimeMillis();
tank.move();
long end=System.currentTimeMillis();
System.out.println("坦克启动时间"+(end-start)+"ms");
}
}
public interface Moveable {
void move() throws Exception;
}
运行效果:同样实现了该需求,并且扩展时会比继承时更方便,也不用多次创建对象,但还不够,这就需要我们的代理模式了解决了:
二、静态代理模式
我们先创建一个接口让Tank去实现它:
public interface Moveable {
void move() throws Exception;
}
public class Tank implements Moveable{
@Override
public void move() throws Exception {
System.out.println("Tank is repairing...");
Thread.sleep(3000);
System.out.println("Tank is moving, calcalcal...");
}
}
下面我们创建两个Tank的代理对象:
public class TankEditor implements Moveable {
Moveable moveable;
public TankEditor(Moveable moveable) {
this.moveable = moveable;
}
@Override
public void move() throws Exception {
long start = System.currentTimeMillis();
moveable.move();
long end = System.currentTimeMillis();
System.out.println("坦克启动时间" + (end - start) + "ms");
}
}
public class TankLogger implements Moveable {
Moveable moveable;
public TankLogger(Moveable moveable) {
this.moveable = moveable;
}
@Override
public void move() throws Exception {
System.out.println("Tank准备启动中.....");
moveable.move();
System.out.println("Tank启动完成....");
}
}
启动类:
public class Main {
public static void main(String[] args) throws Exception {
Moveable moveable = new TankEditor(new TankLogger(new Tank()));
moveable.move();
}
}
运行结果:可以看到通过接口进行聚合代理,我们可以以很低的耦合度来实现各种拓展业务的装配代理,这便是代理模式。当我们需要添加其他拓展代理业务时,直接实现代理接口即可,相当易于拓展。
三、动态代理模式
动态代理模式,一般采用反射来实现,最经典的就是JDK的动态代理,下面是Jdk动态代理原理的链接:JDK动态代理 · java学习笔记 · 看云