Android设计模式之(17)----代理模式

来源:互联网 发布:mac上将pdf转换成txt 编辑:程序博客网 时间:2024/06/05 21:14

代理模式

代理模式属于结构型模式.分为静态代理与动态代理.

比如说 用户现在要买车,只要一辆车直接去车商买,肯定不会卖给你啊.这个时候用户就会找到4S店

让4S店帮忙购买,在从4S那儿买到车子.

在整个交易过程中4S的存在就是一个代理商,用户作为委托者,代理商帮委托者完成委托者的述求.

应用场景

  • 为一个对象的引用提供额外操作
  • 控制一个对象的访问,为不同的用户提供不同的权限级别
  • 被访问对象不想暴露所有细节方法,可代理不想暴露的方法
  • 一个对象不想直接被另一个对象访问

代码示例(静态代理)

(一)抽象购车代理接口

public interface Car {    void buyCar();}

(二)用户实现购车接口

public class UserBuyCar implements Car {    private String name;    @Override    public void buyCar() {        System.out.print("\n"+"用户买了"+getName());    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }}

(三)代理商4S店

public class CarStoreProxy implements Car {    private UserBuyCar car;    public CarStoreProxy(UserBuyCar car) {        this.car = car;    }    @Override    public void buyCar() {        if (car.getName().equals(ProxyTest.AUDI) ||                car.getName().equals(ProxyTest.BMW) ||                car.getName().equals(ProxyTest.BENZ)) {            car.buyCar();        } else {            System.out.print("\n" + "用户什么也没买");        }    }}

(四)调用方式

  //静态代理 买奥迪        UserBuyCar userBuyCar=new UserBuyCar();        userBuyCar.setName(AUDI);        CarStoreProxy audiCarStoreProxy=new CarStoreProxy(userBuyCar);        audiCarStoreProxy.buyCar();        //静态代理 什么也不买        UserBuyCar userBuyCar1=new UserBuyCar();        userBuyCar1.setName(NONE);        CarStoreProxy carStoreProxy=new CarStoreProxy(userBuyCar1);        carStoreProxy.buyCar();

显示结果

用户买了audi用户什么也没买

以上为用户买车过程中,4S作为代理商,用户委托买车的流程案例.实现类和代理类保证统一性必须都实现同一个接口方法.含有具体的代理类.

接口也只能作用于当前这个用户,如果新添加了方法(租车),所有的实现类和代理类都需要实现新方法.

  • 静态代理优点

    • 使用者只需要关注用户业务自身的逻辑
  • 静态代理缺点

    • 一个接口只能作用于一个对象
    • 接口新方法后,所有实现类 代理类都需要新增方法

代码示例(动态代理)

在代理模式中的动态代理,不同于静态代理含有具体代理类.

动态代理中只要通过反射机制动态生成代理类,具体代理对象在运行时生成.

Java动态代理Proxy

/获取指定代理对象所关联的调用处理器  static InvocationHandler getInvocationHandler(Object proxy )  获取关联于指定类装载器和一组接口的动态代理类的类对象  static Class getProxyClass(ClassLoader loader,Class[] interfaces)  判断指定类对象是否是一个动态代理类  static boolean isProxyClass(Class cl )    为指定类装载器、一组接口及调用处理器生成动态代理类实例static Object newProxyInstance(ClassLoader loader,  Class[] interfaces, InvocationHandler  h )

newProxyInstance第三个参数中的InvocationHandler含有一个invoke方法,实现对委托者代理访问,在每次动态代理都需要通过它指定的调用器对象.

  @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {            Object result = method.invoke(object,args);            return result;    }

实现InvocationHandler定义动态代理类

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 {            Object result = method.invoke(object,args);            return result;    }}

调用方式

        //动态代理 买奔驰        UserBuyCar userBuyCar2=new UserBuyCar();        userBuyCar2.setName(BENZ);        DynamicProxy dynamicProxy=new DynamicProxy(userBuyCar2);        Car car=(Car) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Car.class},  dynamicProxy);        car.buyCar();

显示结果

用户买了benz

结果与静态代理效果一致,调用只需要传入具体的委托者即可动态生成代理类.相比于静态代理更为灵活方便

github源码地址