您当前的位置: 首页 > 

命运之手

暂无认证

  • 1浏览

    0关注

    747博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【设计模式】【08】代理模式

命运之手 发布时间:2022-04-13 11:45:26 ,浏览量:1

应用场景

代理模式,英文名Proxy Pattern

该模式用一个代理类代替原始类进行工作

使用这种模式,一般是出于以下几种目的

  • 对原始类的功能进行增强、拦截、修改
  • 控制原始类的访问权限
  • 分担原始类的工作负荷

凡是能起到代理工作作用的方式,都可以认为是代理模式,所以它的实现也是多种多样的

我们现在只列举几种主流的实现形式

普通代理

代理类包装了一个原始类,并且实现了和原始类一样的接口,但代理类调用原始类来处理工作


	public interface IAction {
	
	    void handle();
	}
	
	public class Action implements IAction {
	
	    @Override
	    public void handle() {}
	}
	
	public class ProxyAction implements IAction {
	
	    private Action action = new Action();
	
	    @Override
	    public void handle() {
	        System.out.print("before handle");
	        action.handle();
	        System.out.print("after handle");
	    }
	}

强制代理

原始类不执行工作,强制要求使用代理类来执行工作

比如开发组长和普通开发都属于开发,但是开发组长就可以强制要求通过普通开发来完成某些工作


	public interface IAction {
	
	    void handle();
	}
	
	public class Action implements IAction {
	
	    private IAction proxy = null;
	
	    public IAction getProxy() {
	        this.proxy = new ProxyAction(this);
	        return this.proxy;
	    }
	
	    @Override
	    public void handle() {
	        throw new RuntimeException("please use proxy to handle work");
	    }
	}
	
	public class ProxyAction implements IAction {
	
	    private final IAction origin;
	
	    public ProxyAction(IAction origin) {
	        this.origin = origin;
	    }
	
	    @Override
	    public void handle() {
	
	    }
	}

动态代理

在代码运行阶段,通过代码动态创建代理对象,而不是在编码阶段,就已经定义好了代理类

这需要编程语言的支持,并不是所有语言都支持这种特性

Java语言是通过Proxy和InvocationHandler这两个类来实现动态代理功能的


	public interface IAction {
	
	    void handle();
	}
	
	public class Action implements IAction {
	
	    @Override
	    public void handle() {
	        System.out.print("handle");
	    }
	}
	
	public class InvokeHandler implements InvocationHandler {
	
	    private Object obj;
	
	    public InvokeHandler(Object obj) {
	        this.obj = obj;
	    }
	
	    @Override
	    @SneakyThrows
	    public Object invoke(Object proxy, Method method, Object[] args) {
	        if (obj instanceof IAction && method.getName().equals("handle")) {
	            System.out.print("before handle");
	            Object rst = method.invoke(obj, args);
	            System.out.print("after handle");
	            return rst;
	        }
	        return null;
	    }
	}
	
	public class APP {
	
	    public static void main(String[] args) {
	        IAction action = new Action();
	        InvokeHandler handler = new InvokeHandler(action);
	        IAction proxy = (IAction) Proxy.newProxyInstance(action.getClass().getClassLoader(), new Class[]{IAction.class}, handler);
	        proxy.handle();
	    }
	}

Java动态代理实现原理

可以看到,Proxy.newProxyInstance总共接收了三个参数

ClassLoader loader, Class[] interfaces, InvocationHandler handler

loader传入原始对象的ClassLoader即可,这个仅仅是用来创建动态类型用的

具体通过哪个class获取ClassLoader并没有区别,一般用户自定义的class,最终获得的ClassLoader都是同一个

Proxy根据interfaces,来动态创建一个新的类型,这个类型会继承Proxy,并实现interfaces指定的全部接口

当类型定义完成之后,下一步就是动态类中的函数如何实现

这个是通过InvocationHandler,由用户手动去指定的

关注
打赏
1654938663
查看更多评论
立即登录/注册

微信扫码登录

0.0396s