代理模式
2016-03-17 19:50
204 查看
Provide a surrogate or placeholder for another object to control access to it.
真实主题类
代理类
场景类
搞扩展性。具体的角色随时都会发生变化的,只要他实现了接口,都可以通过代理类不做任何的修改的情况下使用。
智能化。Struts是如何把表单映射到表单的。
Spring AOP
强制代理 (从真是角色查找代理角色)
代理是有个性的 (代理角色还可以实现其他的接口)
动态代理
游戏者接口
动态代理者类
真实游戏者类
public class GamePlayer implements IGamePlayer {
场景类
注:InvocationHandler接口是JDK提供的动态代理接口,又被代理类的方法进行代理。
抽象主题
真实主题
动态代理的Handler类
动态代理类
通知类 (接口)
前置通知类
场景类
注:
动态代理的主要意图就是解决常说的“审计”问题,也就是面向切面编程,在不改变我们已有代码结构情况下增强或控制对象的行为。
代理模式的通用类图
代理模式的通用源码
抽象主题类(接口)public interface Subject { // 定义一个方法 public void request(); }
真实主题类
public class RealSubject implements Subject { @Override public void request() { // 业务逻辑处理 System.out.println("HelloWorld"); } }
代理类
public class Proxy implements Subject { //要代理哪个实现类 private Subject subject = null; // 默认被代理者 public Proxy(Subject _subject) { this.subject = _subject; } // 通过构造函数传递代理者 public Proxy(Object ... objects) { } //实现接口中的方法 @Override public void request() { this.before(); this.subject.request(); this.after(); } // 预处理 private void before() { //do Something } // 善后处理 private void after() { //do Something } }
场景类
public class Client { public static void main(String[] args) { Subject realSubject = new RealSubject(); Subject proxy = new Proxy(realSubject); proxy.request(); } }
代理模式的优点
职责清晰。真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件事务,附带的结果就是编程简洁清晰。搞扩展性。具体的角色随时都会发生变化的,只要他实现了接口,都可以通过代理类不做任何的修改的情况下使用。
智能化。Struts是如何把表单映射到表单的。
代理模式的使用场景
打官司为什么要找律师?不想参与中间过程的是是非非,只要完成自己的答辩就成了,其他的如事前调查、时候追查都由律师搞定,目的就是要减轻自己的负担。Spring AOP
代理模式的扩展应用
普通代理强制代理 (从真是角色查找代理角色)
代理是有个性的 (代理角色还可以实现其他的接口)
动态代理
动态代理
动态代理1类图及源码
游戏者接口
public interface IGamePlayer { //登录 public void login(String user, String password); //杀怪 public void killBoss(); //升级 public void upgrade(); }
动态代理者类
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** * 动态代理者类 * @author hsx * */ public class GamePlayerDynamic implements InvocationHandler { // 被代理的实例 Object object = null; // 我要代理谁 public GamePlayerDynamic(Object _object) { this.object = _object; } //调用被代理的方法 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(this.object, args); if (method.getName().equalsIgnoreCase("login")) { System.out.println("有人登录了我的账号"); } return result; } }
真实游戏者类
public class GamePlayer implements IGamePlayer {
private String name = ""; public GamePlayer(String _name) { this.name = _name; } @Override public void login(String user, String password) { System.out.println("登录名" + user + "的用户" + this.name + "登录成功!"); } @Override public void killBoss() { System.out.println(this.name + "正在杀怪"); } @Override public void upgrade() { System.out.println(this.name + "又升了一级"); } }
场景类
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; public class Client { public static void main(String[] args) { IGamePlayer gamePlayer = new GamePlayer("张三"); InvocationHandler handler = new GamePlayerDynamic(gamePlayer); //获得类的class loader ClassLoader c1 = gamePlayer.getClass().getClassLoader(); //动态产生一个代理 IGamePlayer proxy = (IGamePlayer) Proxy.newProxyInstance(c1, new Class[]{IGamePlayer.class}, handler); System.out.println("开始时间---->"); proxy.login("zhangsan", "password"); proxy.killBoss(); proxy.upgrade(); System.out.println("结束时间---->"); } }
注:InvocationHandler接口是JDK提供的动态代理接口,又被代理类的方法进行代理。
动态代理通用类图及源码
抽象主题
public interface Subject { //业务逻辑处理 public void doSomething(String str); }
真实主题
public class RealSubject implements Subject { //业务逻辑处理 @Override public void doSomething(String str) { System.out.println("do something ..." + str); } }
动态代理的Handler类
public class MyInvocationHandler implements InvocationHandler { //被代理的对象 private Object object = null; //普通构造函数传递一个对象 public MyInvocationHandler(Object _object) { this.object = _object; } //代理方法 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(this.object, args); } }
动态代理类
public class DynamicProxy<T> { @SuppressWarnings("unchecked") public static <T> T newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler) { // 寻找JoinPoint连接点 if (true) { //执行一个前置通知 (new BeforeAdvice()).exec(); } return (T) Proxy.newProxyInstance(loader, interfaces, handler); } }
通知类 (接口)
public interface IAdvice { public void exec(); }
前置通知类
public class BeforeAdvice implements IAdvice { @Override public void exec() { System.out.println("我是前置通知,我通知了..."); } }
场景类
public class Client { public static void main(String[] args) { Subject subject = new RealSubject(); InvocationHandler handler = new MyInvocationHandler(subject); Subject proxy = DynamicProxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), handler); proxy.doSomething("Finish"); } }
注:
动态代理的主要意图就是解决常说的“审计”问题,也就是面向切面编程,在不改变我们已有代码结构情况下增强或控制对象的行为。
相关文章推荐
- 《Linux内核设计与实现》 第一二章学习笔记
- 体验:我买过的手机们
- XIB中设置UITextField的高度
- [自动机与树]
- POJ 2002 哈希
- setfilter 使用两个LIKE 问题
- Eclipse中Python插件PyDev的安装与配置流程
- OS X 添加环境变量
- Mysql分页查询
- 移动端屏幕禁止滑动
- final关键词
- Activity全屏设置
- Java集合框架:WeakHashMap
- HDU-1159-最长公共序列模板。。。
- 博主面试经历
- Java集合框架:WeakHashMap
- 【ProjectEuler111】Primes with runs
- C++第2次实验
- Android应用反破解的思路
- 华为:汽水瓶