Android设计模式:代理设计模式

  • 为其他对象提供一种代理以控制这个对象的访问。当一个对象不能或者不想直接访问另一个对象时,可以通过一个代理对象来间接访问。为保证客户端使用的透明性,委托对象和代理对象要实现同样的接口。被访问的对象不想暴露全部内容时,可以通过代理去掉不想被访问的内容。

(1)静态代理:在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了

  • 创建抽象主题类:委托对象和代理对象实现的接口
public interface Subject {
    void request();
}
  • 创建真实主题类:代理所表示的真实对象,执行具体的业务方法
public class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("被代理类方法");
    }
}
  • 创建代理类:持有一个真实类的引用,在接口方法中调用真实主题相应的方法,达到代理的作用。
public class SubjectProxy implements Subject {
    Subject subject;

    public SubjectProxy(Subject subject) {
        this.subject = subject;
    }

    @Override
    public void request() {
        if (realSubject != null) {
            System.out.println("我是代理类");
            subject.request();//调用被代理者方法
        }
    }
}
  • 调用代理类访问
Subject subject = new RealSubject();
SubjectProxy proxy = new SubjectProxy(subject);
proxy.request();

(2)动态代理:类的源码是在程序运行期间根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。

  • 动态代理接口InvocationHandler
  • 创建动态代理类:重写invoke()方法实现自己想要的任务
public class SubjectProxy implements InvocationHandler {
    Object object;//被代理的对象

    public SubjectProxy(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = method.invoke(object,args);
        return result;
    }
}
  • 调用代理类访问
  • 通过Proxy.newProxyInstance方法生成代理类,代理对象。
Subject subject = new RealSubject();//被代理类
SubjectProxy subjectProxy = new SubjectProxy(subject);//创建动态代理
ClassLoader classLoader = subject.getClass().getClassLoader();指定当前目标对象使用类加载器,即目标对象的类加载器。
Subject proxy = (Subject) Proxy.newProxyInstance(classLoader, new Class[]{SubjectProxy.class}, subjectProxy);
proxy.request();

优点

  • 可以通过一个代理类完成全部的代理功能,接口中声明的所有方法都被转移到调用处理器一个集中的方法中处理(InvocationHandler.invoke)。当接口方法数量较多时,我们可以进行灵活处理,而不需要像静态代理那样每一个方法进行中转。
  • 动态代理的应用使我们的类职责更加单一,复用性更强。

缺点

  • 静态代理如果接口新增一个方法,除了所有实现类(真实主题类)需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。
  • 代理对象只服务于一种类型的对象,如果要服务多类型的对象。必须要为每一种对象都进行代理。
  • 不能对类进行代理,只能对接口进行代理,如果我们的类没有实现任何接口,那么就不能使用这种方式进行动态代理。
  • 通过反射拿到方法消耗性能,可能会造成请求处理速度变慢。

你可能感兴趣的:(Android设计模式:代理设计模式)