代理模式

来源:互联网 发布:淘宝几百块发省级期刊 编辑:程序博客网 时间:2024/05/23 10:41

Provide a surrogate or placeholder for another object to control access to it.

代理模式的通用类图

这里写图片描述

代理模式的通用源码

  • 抽象主题类(接口)

    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. 普通代理
  2. 强制代理 (从真是角色查找代理角色)
  3. 代理是有个性的 (代理角色还可以实现其他的接口)
  4. 动态代理

动态代理

动态代理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");    }}

注:

动态代理的主要意图就是解决常说的“审计”问题,也就是面向切面编程,在不改变我们已有代码结构情况下增强或控制对象的行为。

1 0