提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
本人对于设计模式的学习,仅供参考!
一、代理模式Proxy
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。简单来说就是:使用一个代理对象将对象包装起来,然后用该代理对象来取代该对象,任何对原始对象的调用都要通过代理,代理对象决定是否以及何时调用原始对象的方法,也就是为其他对象提供一种代理以控制对这个对象的访问。
这是常见代理模式常见的 UML 示意图。
二、静态代理
1.定义
静态代理:由程序员创建或特定工具自动生成源代码,也就是在编译时就已经将接口,被代理类,代理类等确定下来。在程序运行之前,代理类的.class文件就已经生成。
2.代码实现
假如有一个坦克有一个移动功能,我想在坦克移动时记录坦克移动的时间以及坦克移动时的日志记录。现在用静态代理的方式实现这个案例:
//创建接口
public interface Movable {
//移动
void move() throws InterruptedException;
}
//坦克类
public class Tank implements Movable {
//重写移动功能
@Override
public void move() throws InterruptedException {
System.out.println("ka~ka~ka~~~~~~~~~");
Thread.sleep(1000);
}
}
//代理类,目的:记录日志
public class TankLogProxy implements Movable{
private Movable movable;
public TankLogProxy(Movable movable) {
this.movable = movable;
}
@Override
public void move() throws InterruptedException {
System.out.println("tank start moving.....");
movable.move();
System.out.println("tank is stop.....");
}
}
//代理类,目的:记录坦克移动时间。
public class TankTimeProxy implements Movable {
private Movable movable;
public TankTimeProxy(Movable movable) {
this.movable = movable;
}
@Override
public void move() throws InterruptedException {
long timeStart=System.currentTimeMillis();
movable.move();
long timeEnd=System.currentTimeMillis();
System.out.println("tank moving time is "+(timeEnd-timeStart)+" ms");
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
new TankLogProxy(
new TankTimeProxy(
new Tank()
)
).move();
}
}
测试结果:
tank start moving.....
ka~ka~ka~~~~~~~~~
tank moving time is 1015 ms
tank is stop.....
Process finished with exit code 0
总结
使用了静态代理模式情况下,我们没有修改tank类中的业务代码,而是选择以代理类的方式增强了他的功能,耦合度低,可扩展性好。静态代理由于不需要反射获取目标对象,所以性能也更好。
但代理模式会造成系统设计中类的数量增加,在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢,同时也增加了系统的复杂度。
版权声明:本文为yz1925506412原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。