android 设计框架Android知识Android开发

Android设计模式(十七)-代理模式

2017-04-07  本文已影响1370人  喵了个呜s

代理模式也叫委托模式,是结构型设计模式。代理就是让别人帮你做事,比如帮你带饭,请律师打官司什么的。

博客地址

定义

为其他对象提供一种代理以控制对这个对象的访问。

使用场景

UML

简单实现

就以打官司为例。我们一般人要打官司都要找个律师来代理。

静态代理

先建立一个起诉类的接口:

public interface ILawsuit {
    void submit();//提交申请
    void burden();//进行举证
    void defend();//开始辩护
    void finish();//诉讼完成
}

真正的起诉者:

public class Civilian implements ILawsuit {
    @Override
    public void submit() {
        System.out.println("起诉");
    }

    @Override
    public void burden() {
        System.out.println("举证");
    }

    @Override
    public void defend() {
        System.out.println("辩护");
    }

    @Override
    public void finish() {
        System.out.println("胜诉");
    }
}

找的律师:

public class Lawyer implements ILawsuit {
    private ILawsuit civilian;

    public Lawyer(ILawsuit civilian) {
        this.civilian = civilian;
    }

    @Override
    public void submit() {
        civilian.submit();
    }

    @Override
    public void burden() {
        civilian.burden();
    }

    @Override
    public void defend() {
        civilian.defend();
    }

    @Override
    public void finish() {
        civilian.finish();
    }
}

客户端调用,调用律师的方法,通过律师调用真正的su起诉者的方法。

public class Client {
    public static void main(String[] args) {
        ILawsuit civilian = new Civilian();
        ILawsuit lawyer = new Lawyer(civilian);
        lawyer.submit();
        lawyer.burden();
        lawyer.defend();
        lawyer.finish();
    }
}

输出:


一个代理可以代理多个类,就像这个律师可以给很多人打官司,只需要在实现一个具体的ILawsuit就行了。代理会根据传进来的被代理者调用传进来的被代理者的方法。

动态代理

代理模式大致分为两大部分:静态代理和动态代理。

上面是是一种静态代理,代理者的代码时先生成写好,然后再对其进行编译,在代码运行前,代理类的class编译文件就已经存在了。

动态代理是相反的,通过反射动态的生成代理者对象,也就是说在写代码的时候根本不知道要代理谁,具体代理谁会在执行阶段决定。

Java提供了一个便捷的动态代理接口InvocationHandler,动态代理类只要实现这个接口就行:

public class DynamicProxy implements InvocationHandler {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return null;
    }
}

看一下动态代理的用法:

public class DynamicProxy implements InvocationHandler {
    private Object object;

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

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //当然这里可以对方法名进行判断过滤 if(method.getName().equals("***"))
        Object result = method.invoke(object,args);
        return result;
    }
}

客户端调用:

public class Main {
    public static void main(String[] args) {
        ILawsuit lawsuit = new Civilian();
        DynamicProxy proxy = new DynamicProxy(lawsuit);
        ClassLoader loader = lawsuit.getClass().getClassLoader();
        //动态创建代理类,需要传入一个类加载器ClassLoader;一个你希望这个代理实现的接口列表,这里要代理ILawsuit接口;
        //和一个InvocationHandler的实现,也就是前面创建的proxy。
        ILawsuit lawyer = (ILawsuit) Proxy.newProxyInstance(loader,new Class[]{ILawsuit.class},proxy);
        lawyer.submit();
        lawyer.burden();
        lawyer.defend();
        lawyer.finish();
    }
}

输出和上面一毛一样:

动态代理并不局限与代理一个接口的实现,可以根据运行时传入的接口,动态的生成代理类,然后通过Method的invoke方法来执行被代理类的真实方法。非常灵活。

其他分类

静态代理和动态代理是从code方便进行分类的。这两个分类根据适用范围来分都可以分为下面几种:

总结

代理模式使用非常广泛,从分类就能感觉出来,而且其他的设计模式中也会有代理模式的影子。

优点

优点可以从他的适用范围看出来

缺点

上一篇下一篇

猜你喜欢

热点阅读