博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java代理模式之静态代理
阅读量:7019 次
发布时间:2019-06-28

本文共 3172 字,大约阅读时间需要 10 分钟。

  作为一个初级开发者,可能不会接触到代理模式,但是在很多框架的使用中都不知不觉使用了代理模式,比如servlet的过滤器链,spring的AOP,以及spring mvc的拦截器等。所以了解代理模式对于个人的成长是不可避免的。

  在某些情况下,一个客户不想或者不能直接引用一个对象,此时可以通过一个称之为“代理”的第三者来实现间接引用。代理对象可以在客户端和目标对象之间起到中介的作用,并且可以通过代理对象去掉客户不能看到的内容和服务或者添加客户需要的额外服务。

原文和作者一起讨论:http://www.cnblogs.com/intsmaze/p/6013461.html

    
通过引入一个新的对象来实现对真实对象的操作或者将新的对象作为真实对象的一个替身,这种实现机制即为代理模式,通过引入代理对象来间接访问一个对象,这就是代理模式的模式动机。 
 
    
代理模式(Proxy Pattern) :给某一个对象提供一个代理,并由代理对象控制对原对象的引用。代理模式的英文叫做Proxy或Surrogate,它是一种对象结构型模式。
    
代理模式示意结构图比较简单,一般可以简化为如下图所示,但是在现实中要复杂很多。
 
如下的场景来理解为什么采用聚合而不是继承调用:
public interface Moveable {    void move();    void stop();}public class Tank implements Moveable {    public void move() {                System.out.println("Tank Move");        try {            Thread.sleep(new Random().nextInt(10000));        } catch (InterruptedException e) {            e.printStackTrace();        }            }        public void stop() {               System.out.println("Tank stop");    }    }
现在我们要增加一个功能,记录move方法的执行时间,不能修改源码。

方式1:采用继承

public class Tank1 extends Tank {    public void move() {                System.out.println("time start");        super.move();        System.out.println("time end");    }    }

再增加一个功能,记录move的执行前后的日志信息,不能修改源码。

public class Tank2 extends Tank {    public void move() {                System.out.println("log start");        super.move();        System.out.println("log end");    }    }
但是要是想先记录日志在记录时间,那么就要再创建一个类继承Tank1类。
要先记录时间再记录日志,就要再创建一个类继承Tank2类。
代理模式不采用继承模式,因为扩展性很差的。
 

方式二:采用聚合模式

public class TimeProxy implements Moveable {    Moveable m;       public TimeProxy(Moveable m) {        super();        this.m = m;    }    public void move() {                System.out.println("time start");        m.move();        System.out.println("time end");    }    } public class LogProxy implements Moveable {    Moveable m;       public LogProxy(Moveable m) {        super();        this.m = m;    }    public void move() {                System.out.println("log start");        m.move();        System.out.println("log end");    }    }

想添加日志功能

public static void main(String[] args) throws Exception {        Moveable t = new Tank();        Moveable m=new LogProxy(t);        m.move();    }

想先日志再时间,直接在调用处进行组合,不需要创建新的类

public static void main(String[] args) throws Exception {        Moveable t = new Tank();        Moveable m=new LogProxy(t);        Moveable s=new TimeProxy(m);        s.move();    }

如果要对Moveable接口中所有的方法加时间计算

public class TimeProxy implements Moveable {    Moveable m;       public TimeProxy(Moveable m) {        super();        this.m = m;    }    public void move() {             this.before();        m.move();        this.after();        }    @Override    public void stop() {             this.before();        m.stop();        this.after();           }        public void before()    {        System.out.println("time start");    }    public void after()    {        System.out.println("time end");    }}

代理模式的优点

代理模式能够协调调用者和被调用者,在一定程度上降低了系统的耦合度。
远程代理使得客户端可以访问在远程机器上的对象,远程机器可能具有更好的计算性能与处理速度,可以快速响应并处理客户端请求。
虚拟代理通过使用一个小对象来代表一个大对象,可以减少系统资源的消耗,对系统进行优化并提高运行速度。
保护代理可以控制对真实对象的使用权限。

代理模式的缺点

由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

 

 

你可能感兴趣的文章
ceph mon 添加
查看>>
pycharm改的骚一点
查看>>
Java学习路线
查看>>
自写的类似JS的trim方法
查看>>
用 Java 实现断点续传 (HTTP)
查看>>
电子邮件sendmail的加密(SSL)和认证
查看>>
svn部署大中小型企业上线解决方案(四)
查看>>
挨踢部落故事汇(8):追随梦想坚定创业
查看>>
chart图表的毛病儿~持续更新
查看>>
hdu2030—— 汉字统计
查看>>
Linux基础网络设置
查看>>
全国各地×××指南
查看>>
使用FileWriter可以写UTF-8的解决方法
查看>>
fragment 传值
查看>>
maven webapp
查看>>
Thrift Java实战
查看>>
Web与IMS业务融合技术探讨
查看>>
Python 读取xml文件错误:ExpatError: not well-formed
查看>>
centos流量监控工具iftop的安装及使用
查看>>
分布式关系数据库测试
查看>>