代理模式(Proxy)

来源:互联网 发布:私募模拟交易系统源码 编辑:程序博客网 时间:2024/05/21 10:18

代理模式(Proxy)

概述

代理模式也称委托模式,是一种结构型设计模式,代理类为真实对象提供一种代理以控制对这个对象的访问,以及为委托类提供消息的预处理和消息被委托类处理后的后续处理。为了保证客户端使用的透明性,代理对象和委托对象需要实现相同的接口。代理模式分为静态代理和动态代理。
静态代理是由程序员创建代理类再对其编译,即在编译期代理类的.class文件就已经存在了。
动态代理是在程序运行时运用反射机制动态创建而成的。

类图

代理模式

模式角色

  • 抽象对象角色(Subject):声明了代理对象和委托对象的共同接口(既可以是抽象类也可以是一个接口),这样一来在任何可以使用目标委托对象的地方都可以使用代理对象。
  • 委托对象角色(RealSubject):定义了代理对象所代表的目标对象。
  • 代理对象角色(ProxySubject):代理对象持有一个委托对象的引用,从而可以在任何时候操作目标对象;代理对象通常在客户端调用传递给委托对象之前或之后,执行某个操作,而不是单纯地将调用传递给委托对象。

代码

静态代理

//Subject.javapublic abstract class Subject {    public abstract void operate();}
//RealSubject.javapublic class RealSubject extends Subject {    @Override    public void operate() {    }}
//ProxySubject.javapublic class ProxySubject extends Subject {    private RealSubject mSubject;//持有委托类的引用    public ProxySubject(RealSubject subject) {        this.mSubject = subject;    }    @Override    public void operate() {        //1.pre-process        //2.调用委托类的方法         mSubject.operate();        //3.post-process    }}
//Client.javapublic class Client {    public static void main(String[] args) {        RealSubject real = new RealSubject();        ProxySubject proxy = new ProxySubject(real);        proxy.operate();    }}

动态代理

//DynamicProxy.javapublic class DynamicProxy implements InvocationHandler {    private Object mObject;//委托类的引用    public Object newProxyInstance(Object targetObject) {        this.mObject = targetObject;        return Proxy.newProxyInstance(mObject.getClass().getClassLoader(),                    mObject.getClass().getInterfaces(), this);    }    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        try {            //1.pre-process            //2.调用委托类的方法            Object result = method.invoke(obj, args);            //3.post-process            return result;        } catch (Exception e) {        }        return null;    }}
//Client.javapublic class Client {    public static void main(String[] args) {        DynamicProxy proxy = new DynamicProxy();        Subject subject = (Subject)proxy.newProxyInstance(new RealSubject());        subject.operate();    }}

总结

静态代理优点:

客户端不需要知道实现类是什么,只需要知道代理类即可,实现客户端和实现类(委托类)的解耦。上面的new RealSubject()可以用工厂方法进行隐藏。

静态代理的缺点:

  • 代理类和委托类实现了相同的接口,出现了大量的重复性的代码,当接口增加一个方法,除了所有的实现类需要实现这个方法之外,所有的代理类也需要实现此方法,不易维护。
  • 代理对象只服务于一种类型的对象,如果要服务于多类型的对象,必须要为每一钟对象都进行代理,增加了很多的类。

动态代理优点:

相比于静态代理,动态代理不需要在抽象对象的所有方法都进行中转,所有的方法均转到invoke中处理,代码更简洁,灵活性更高。动态代理可以代理多个委托对象,而静态代理只能代理某个类型的对象。

使用场景

  • 安全代理,可以控制对真实对象访问的权限,如不同的调用者需要控制不同的权限
  • 开闭原则,若需要对实现类进行扩展,但是又不可修改实现类时,可以增加代理类,然后扩展代理类。

Android平台下设计模式

ActivityManagerProxy

这里ActivityManagerProxy和ActivityManagerNative都是继承自IActivityManager,ActivityManagerProxy是代理类,ActivityManagerNative是委托类,但是ActivityManagerNative是抽象类,具体的功能是由ActivityManagerService来完成的,所以实际上ActivityManagerService是委托类。不过ActivityManagerProxy和ActivityManagerService是运行在不同的进程中,中间是通过Android binder机制来实现的跨进程通信

参考
http://www.cnblogs.com/java-my-life/archive/2012/04/23/2466712.html
Android源码设计模式解析与实战

原创粉丝点击