代理设计模式

1.我理解的代理设计模式

字面意思是代为处理的意思。举个例子:

  • 需求:出一盘菜
  • 处理方式:厨师炒一盘就行了
  • 问题:口味不满足我的要求怎么办

再举个项目中的例子

  • 需求:上传文件到服务器
  • 处理方式:去github找个网络相关项目,实现上传文件
  • 问题:那个项目实现了上传文件,但是我想监听上传的进度,实时显示出来怎么办

这就需要代理模式了,我自己来处理这些事,同时加上我自己想要的功能

  • 我自己炒菜,满足需求了,我炒菜的同时我还可以依照自己的口味多加点酱油
  • 上传文件时,我写个子类继承上传文件操作,这样不影响框架的其他功能,同时在上传文件时我还可以加点操作,每隔100ms获取一下上传了多少反馈出去

这就是代理模式,你已经实现了这个功能,但是我来做个代理,原先实现的我原封不动照办,但是会加点自己的东西

2.Java中动态代理

首先有个接口,可以做炒菜操作

public interface ICook {
    public void doCook();
}
复制代码

来个实体类,实现这个接口

public class Man implements ICook {

    @Override
    public void doCook() {
        System.out.println("出菜");
    }
}
复制代码

出菜了

Man man = new Man();
man.doCook();
复制代码

接下来在改变Man中doCook()方法,在炒菜前加点香葱 用来动态代理的类

public class CookInvocationHandler implements InvocationHandler{
    /**
     * 被代理的对象
     */
    private Object mObject;

    public CookInvocationHandler(Object object){
        this.mObject = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("加点香葱");
        Object object = method.invoke(mObject,args);
        return object;
    }
}
复制代码

使用代理来出菜

public static void main(String[] args) {
        Man man = new Man();

        ICook cooker =
                (ICook) Proxy.newProxyInstance(
                        ICook.class.getClassLoader(), // ClassLoader
                        new Class<?>[]{ICook.class}, // 目标接口
                        new CookInvocationHandler(man) // InvocationHandler
                );
        // 当调用这个方法的时候调用 CookInvocationHandler的invoke 法
        cooker.doCook();
}
复制代码

3.应用场景

Retrofit的创建就是使用了这个设计模式

public <T> T create(final Class<T> service) {
    Utils.validateServiceInterface(service);
    if (validateEagerly) {
      eagerlyValidateMethods(service);
    }
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
        new InvocationHandler() {
          private final Platform platform = Platform.get();

          @Override public Object invoke(Object proxy, Method method, Object... args)
              throws Throwable {
            // If the method is a method from Object then defer to normal invocation.
            if (method.getDeclaringClass() == Object.class) {
              return method.invoke(this, args);
            }
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            ServiceMethod serviceMethod = loadServiceMethod(method);
            OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  }
复制代码

好处是,将内部网络请求和外部调用充分的解耦

转载于:https://juejin.im/post/5cd282aaf265da035f6fef50

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值