设计模式——代理模式
来源:互联网 发布:招聘网络平面设计师 编辑:程序博客网 时间:2024/05/21 08:58
代理对于我们来说再熟悉不过了,比如:代理商,代理律师。那么代理的到底是什么含义呢?代理就是受委托代表当事人进行某种活动。那么代理模式的核心作用是什么呢?就是通过代理,控制对象的访问。可以详细的控制访问某个或者是某类对象的方法,在调用这个方法前做前置处理,调用这个方法后做后置处理。
代理是在需要用比较通用和复杂的对象指针代替简单的指针的时候,使用代理模式。
下面是一些可以使用代理 模式常见情况:
1.远程代理为一个对象在不同的地址空间提供局部代表。
2.虚代理根据需要创建开销很大的对象,使得此对象只在需要时才会真正创建。
3.保护代理控制对原始对象的访问。
4.智能指引取代了简单的指针,它在访问对象时执行一些附加操作。
5.防火墙代理,保护目标,不让恶意用户接近。
代理又分为静态代理(静态定义代理类)和动态代理(动态生成代理类)两种。
动态代理相比较静态代理而言在抽象角色中(接口)声明的所有方法都被转移到调用处理器一个集中的方法中处理,这样的好处就是我们可以更加灵活和统一的处理众多的方法。
举个例子:假如说我在北京工作,接了一个上海的项目,但是由于太远我又不想去上海,怎么办呢?此时刚好我一个同学在上海上班,于是我就跟我的同学联系,让他帮我把这个项目谈过来。接项目肯定需要 面谈—>起草合同—>收首款—>做项目—>收尾款。除了完成项目的过程是由我本人执行之外,其他的都是由我同学来处理的,那么我同学所起的作用就是代理。
静态代理模式为
接项目过程
public interface Project { String interview(); String drafContract(); String receiveFirst(); String doProjects (); String endParagraph();}
本人自己
public class Mine implements Project { @Override public String interview() { return "Mine--->interview"; } @Override public String drafContract() { return "Mine--->drafContract"; } @Override public String receiveFirst() { return "Mine--->receiveFirst"; } @Override public String doProjects() { return "Mine--->doProjects"; } @Override public String endParagraph() { return "Mine--->endParagraph"; }}
同学代理
public class ProxySchoolmate implements Project{ private Mine mine; public ProxySchoolmate(Mine mine) { this.mine = mine; } @Override public String interview() { return "ProxySchoolmate--->interview"; } @Override public String drafContract() { return "ProxySchoolmate--->drafContract"; } @Override public String receiveFirst() { return "ProxySchoolmate--->receiveFirst"; } @Override public String doProjects() { return mine.doProjects(); } @Override public String endParagraph() { return "ProxySchoolmate--->endParagraph"; }}
测试
Mine mine = new Mine(); ProxySchoolmate proxySchoolmate = new ProxySchoolmate(mine); System.out.println(proxySchoolmate.interview()); System.out.println(proxySchoolmate.drafContract()); System.out.println(proxySchoolmate.receiveFirst()); System.out.println(proxySchoolmate.doProjects()); System.out.println(proxySchoolmate.endParagraph());
运行效果
动态代理模式为
接项目过程和本人自己的内容完全相同,不同的是同学代理少了构造方法,多了一个动态代理机制的类
同学代理
public class ProxySchoolmate implements Project { @Override public String interview() { return "ProxySchoolmate--->interview"; } @Override public String drafContract() { return "ProxySchoolmate--->drafContract"; } @Override public String receiveFirst() { return "ProxySchoolmate--->receiveFirst"; } @Override public String doProjects() { return "ProxySchoolmate--->doProjects"; } @Override public String endParagraph() { return "ProxySchoolmate--->endParagraph"; }}
动态代理机制类
public class ProjectHandler implements InvocationHandler { Mine mine; ProxySchoolmate proxySchoolmate = new ProxySchoolmate(); public ProjectHandler(Mine mine) { this.mine = mine; } @Override public Object invoke(Object proxy, Method method, Object[] objects) throws Throwable { System.out.println(proxySchoolmate.interview()); System.out.println(proxySchoolmate.drafContract()); System.out.println(proxySchoolmate.receiveFirst()); if (method.getName().equals("doProjects")) { proxy = method.invoke(mine, objects); System.out.println(proxy.toString()); } System.out.println(proxySchoolmate.endParagraph()); return proxy; }}
测试
Mine mine = new Mine();ProjectHandler handler = new ProjectHandler(mine);Project project = (Project) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),new Class[]{Project.class},handler);project.doProjects();
运行效果与上面的运行效果相同。
下面来说一下动态代理机制
动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(接口)、另一个则是 Proxy(类),这一个接口和一个类是实现我们动态代理必不可少的。上面的使用也许大家已经看到了。如果我们要实现一个动态代理类首先必须要实现InvocationHandler这个接口,而且这个代理类实例需要关联到了一个handler,当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转化为由InvocationHandler这个接口的 invoke 方法来进行调用。上面的ProjectHandler 这个类就是最好的证明。那么invoke(Object proxy, Method method, Object[] objects) throws Throwable 这个方法里面的三个参数各代表什么呢?
proxy:就是我们所代理的那个真实对象
method:就是我们所要调用真实对象的某个方法的Method对象
objects:就是调用真实对象某个方法时接受的参数
Proxy这个类的作用就是用来动态创建一个代理对象的类,它提供了许多的方法,但是我们用的最多的就是 newProxyInstance 这个方法,源码为
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
我们使用时为Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),new Class[]{Project.class},handler)这个方法里面也有三个参数,各代表什么呢?
loader:一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
interfaces:一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
h:一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上。
好了动态代理到此也就结束了,整个代理模式也就到这里了。
- 设计模式—代理模式
- 设计模式—代理模式
- 设计模式—代理模式
- 设计模式—代理模式
- 设计模式—代理模式
- 设计模式—代理模式
- 设计模式—代理模式
- 设计模式—代理模式
- 设计模式—代理模式
- 设计模式—代理模式
- 设计模式——代理设计模式
- 设计模式——代理设计模式
- 每日设计模式——代理模式
- 学习设计模式——代理模式
- java设计模式——代理模式
- 设计模式——策略、代理模式
- 设计模式——代理模式(Proxy)
- 设计模式——代理模式
- Tensorflow 变量命名空间及变量重用
- poj 3693连续重复最多的串
- C++
- 51单片机之声双色点阵驱动
- RESTful
- 设计模式——代理模式
- 263. Ugly Number
- [容斥原理] BZOJ 2839 集合计数
- OC中与copy有关的那些事 一 (copy与声明NSString属性 : strong/copy 的关系)
- 广告行业eCPM概念
- linux shell 获取当前正在执行脚本的绝对路径
- linux下多线程之生成者与消费者模型(互斥,读写锁,条件变量)
- onCreateContextMenu用法
- 接口三