设计模式-结构型-代理模式(Proxy)
2016-11-12 12:37
549 查看
又叫委托模式
Provide a surrogate or placeholder for another object to control access to it.
具体主题角色(ConcreteSubject):业务逻辑的具体执行者
代理角色(Proxy):负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并且在真实主题角色处理完毕前后做预处理和善后工作
高扩展性
智能化
如果要按照上面的方法使用代理模式,那么真实角色必须是事先已经存在的,并将其作为代理对象的内部属性。但是实际使用时,一个真实角色必须对应一个代理角色,如果大量使用会导致类的急剧膨胀;此外,如果事先并不知道真实角色,该如何使用代理呢?这个问题可以通过动态代理来解决
这里需要注意的是抽象主题角色不能用抽象类,只能用接口,因为
定义
为其它对象提供一种代理以控制对这个对象的访问Provide a surrogate or placeholder for another object to control access to it.
角色
抽象主题角色(Subject):可以是一个抽象类或者一个接口具体主题角色(ConcreteSubject):业务逻辑的具体执行者
代理角色(Proxy):负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并且在真实主题角色处理完毕前后做预处理和善后工作
优点
职责清晰高扩展性
智能化
应用场景
Spring AOPpackage com.vapy.structure.Proxy; /** * * @author vapy 2016年11月10日 * */ public abstract class Subject { public abstract void request(); }
package com.vapy.structure.Proxy; /** * * @author vapy 2016年11月10日 * */ public class RealSubject extends Subject { @Override public void request() { System.out.println("RealSubject request"); } }
package com.vapy.structure.Proxy; /** * * @author vapy 2016年11月10日 * */ public class Proxy { // 对真实角色的引用 private RealSubject real; public void request() { // 真实角色操作前的附加操作 this.preRequest(); if(null == real) { real = new RealSubject(); } real.request(); // 真实角色操作后的附加操作 this.postRequest(); } public void preRequest() { System.out.println("pre request"); } public void postRequest() { System.out.println("post request"); } }
如果要按照上面的方法使用代理模式,那么真实角色必须是事先已经存在的,并将其作为代理对象的内部属性。但是实际使用时,一个真实角色必须对应一个代理角色,如果大量使用会导致类的急剧膨胀;此外,如果事先并不知道真实角色,该如何使用代理呢?这个问题可以通过动态代理来解决
package com.vapy.structure.Proxy.dynamic; /** * * @author vapy 2016年11月11日 * */ public interface Subject { public abstract void request(); }
package com.vapy.structure.Proxy.dynamic; /** * * @author vapy 2016年11月11日 * */ public class RealSubject implements Subject { @Override public void request() { System.out.println("RealSubject request"); } }
package com.vapy.structure.Proxy.dynamic; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** * * @author vapy 2016年11月11日 * */ public class DynamicSubject implements InvocationHandler { Object sub; public DynamicSubject(Object obj) { this.sub = obj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before calling:" + method); method.invoke(sub, args); System.out.println("after calling:" + method); return null; } }
package com.vapy.structure.Proxy.dynamic; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; /** * * @author vapy 2016年11月11日 * */ public class Client { public static void main(String[] args) { Subject realSubject = new RealSubject(); InvocationHandler handler = new DynamicSubject(realSubject); Subject subject = (Subject)Proxy.newProxyInstance(handler.getClass().getClassLoader(), realSubject.getClass().getInterfaces(), handler); subject.request(); } }
这里需要注意的是抽象主题角色不能用抽象类,只能用接口,因为
Proxy.newProxyInstance需要接收接口数组,使生成的对象
class com.sun.proxy.$Proxy0能够转换成这些接口的类型(泛型),如果使用抽象类,则会转换失败
相关文章推荐
- 【设计模式学习笔记十三】【结构型模式】【代理模式(Proxy)】
- 设计模式-结构型模式:代理模式 Proxy
- 设计模式(十一)代理模式Proxy(结构型)
- 设计模式(12)--Proxy(代理模式)--结构型
- 设计模式十三:proxy(代理)——对象结构型模式
- 设计模式(12)-结构型-代理模式(Proxy)
- 设计模式(十一)代理模式Proxy(结构型)
- 设计模式(十一)代理模式Proxy(结构型)
- 设计模式(十一)代理模式Proxy(结构型)
- 设计模式之代理(Proxy)----对象结构型模式
- 【设计模式】结构型模式之Proxy代理
- [设计模式-结构型]代理模式(Proxy)
- 设计模式(3)-结构型-代理模式(proxy)以及java动态代理的两种方式
- 设计模式12---设计模式之代理模式(Proxy)(结构型)
- PHP设计模式:结构型之代理(Proxy)
- 设计模式(3)-结构型-代理模式(proxy)以及java动态代理的两种方式
- 设计模式(十一)代理模式Proxy(结构型)
- 【设计模式基础】结构型模式 - 7 - 代理(Proxy)
- 设计模式(3)-结构型-代理模式(proxy)以及java动态代理的两种方式
- 设计模式12: Proxy 代理模式(结构型模式)