前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >代理模式

代理模式

作者头像
发布2019-04-18 16:45:15
2950
发布2019-04-18 16:45:15
举报
文章被收录于专栏:WD学习记录WD学习记录

代理模式:为其他对象提供一种代理以控制对对象的访问

主要解决:直接访问对象时带来的问题,比如,要访问的对象在远程机器上,有些对象由于某些原因,创建开销很大,或者操作需要安全控制,或者需要进程外的访问。直接访问会给使用者带来很多麻烦,因此可以在访问对象时加上一个对此对象的访问层。

应用实例:windows快捷方式,spring aop

优点:1 职责清晰 2 高扩展性 3 智能化

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

使用场景:1. 远程代理 2. 虚拟代理 3. Copy-on-write代理 4. 保护代理(Protect or Access)5. Cache代理 6. 防火墙代理 7. 同步化代理(Synchronization) 8. 智能引用代理(smart reference)

代理模式和适配器模式的区别:适配器模式主要改变所考虑对象的接口,代理模式不能改变所代理类的接口

代理模式和装饰器模式的区别:装饰器模式是为了增强功能,代理模式是为了加以控制。

静态代理实例:

代码语言:javascript
复制
public interface Movable {
    void move();
}
代码语言:javascript
复制
public class TankTimeProxy implements Movable {
    private Movable tank;

    public TankTimeProxy(Movable tank){
        this.tank=tank;
    }

    @Override
    public void move(){
        long start=System.currentTimeMillis();
        System.out.println("start time : " +start);
        tank.move();
        long end=System.currentTimeMillis();
        System.out.println("end time : "+end);
        System.out.println("spend all time :"+(end-start)/1000+"s.");
    }
}
代码语言:javascript
复制
public class TankLogProxy implements Movable{
    private Movable tank;
    public TankLogProxy(Movable tank){
        this.tank=tank;
    }

    @Override
    public void move(){
        System.out.println("tank move start");
        tank.move();
        System.out.println("tank move end");
    }
}
代码语言:javascript
复制
Movable target=new TankLogProxy(new TankTimeProxy(new Tank()));
target.move();

动态代理实例:

代码语言:javascript
复制
public class MyTimeProxyInvokeHandler implements InvocationHandler {
    private Object target;

    public  MyTimeProxyInvokeHandler(Object target){
        this.target=target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
        long start=System.currentTimeMillis();
        System.out.println("start time :"+start);
        method.invoke(target,args);
        long end=System.currentTimeMillis();
        System.out.println("end time : "+end);
        System.out.println("spend all time : "+(end-start)/1000+"s.");
        return null;
    }
}
代码语言:javascript
复制
Movable tank=new Tank();
MyTimeProxyInvokeHandler myTimeProxyInvokeHandler=new MyTimeProxyInvokeHandler(tank);
Movable tankProxy=(Movable)Proxy.newProxyInstance(tank.getClass().getClassLoader(),tank.getClass().getInterfaces(),myTimeProxyInvokeHandler);
tankProxy.move();

这种方式为JDK的Proxy代理实现,目标类与代理类实现相同的接口,目标类不存在接口,只能使用CGLIB来解决。

CGLIB代理生成原理是生成目标类的子类,子类是增强过的,子类对象就是代理对象。

CGLIB实现代理模式:

代码语言:javascript
复制
public class Tank2 {
    public void move(){
        System.out.println("Tank Moving ,....");
        try{
            Thread.sleep(new Random().nextInt(5000));
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}
代码语言:javascript
复制
public class MyTimeProxyInvokeHandler implements InvocationHandler {
    private Object target;

    public  MyTimeProxyInvokeHandler(Object target){
        this.target=target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
        long start=System.currentTimeMillis();
        System.out.println("start time :"+start);
        method.invoke(target,args);
        long end=System.currentTimeMillis();
        System.out.println("end time : "+end);
        System.out.println("spend all time : "+(end-start)/1000+"s.");
        return null;
    }
}
代码语言:javascript
复制
Tank2 proxyTank=new MyCglibFactory(new Tank2()).myCglibCreator();
proxyTank.move();

参考:

菜鸟教程-代理模式

代理模式

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年04月11日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档