美文网首页
学习代理模式----实现快速切换网络访问框架

学习代理模式----实现快速切换网络访问框架

作者: 三棵柚子 | 来源:发表于2018-05-14 17:57 被阅读0次

    前言


    最近在慢慢的看java的设计模式,作为一个安卓开发,了解设计模式是非常有必要的,对于你技术的沉淀和你对整体架构的设计都会提供一个非常好的思路今天我想和大家分享下以下知识点:

    • 什么是代理模式?
    • 代理模式的思考方式
    • 代理模式能够做什么?(手写一个实现快速切换网络访问框架的例子)

    我希望大家带着这三个问题,对设计模式进行一些学习和讨论, 首先我们来说下我们的第一个主题
    

    什么是代理模式?

    先举个比较简单的例子, 我们通常买房的话,不会直接和房子的拥有者打交道,而是和房产中介或者说房产公司打交道,那么我们把这个过程剖析一下,我们可以简化为三个部分:

    * 买房者(真实想要买房子的人)
    * 中介(不能真实提供房子,但提供卖房行为)
    * 卖房者(真实提供房子的人,不提供卖房行为)
    

    *上面的逻辑就是一个完整代理模式的案例,我们可以从抽取的角度来思考代理模式:

    就像我们找工作一样, 我们通常不会直接去企业问是否能够提供相应的岗位, 而是通过一些招聘网站来获取一些
    企业的招聘信息, 这里的招聘网站就相当于是代理, 而求职者就是具备需要行为的对象,网站上的公司就是提供需
    要行为的对象,这样就能够有利的隔离面试者和公司在面试.*
    

    代理模式的思考方式

    当我们需要进行某一个行为的时候,我们不直接和具备这一行为的对象进行接触,而是通过一些方式,达到我们的目的, 一般来说,使用代理模式,都是想既要达到功能,又要能很好的进行隔离,作为程序员,我想应该可以解决很多时间问题, 特别是存在那种耦合非常强的代码中,使用代理模式能够有效隔离真实调用的代码,达到解耦合的效果!


    代理模式能够做什么?(手写一个实现快速切换网络访问框架的例子)

    还记得我们上面讲的三个对象么?

      * 买房者(真实想要买房子的人)
      * 中介(不能真实提供房子,但提供卖房行为)
      * 卖房者(真实提供房子的人,不提供卖房行为)
    

    第一步,首先我们编写买房者的逻辑(主要体现的是行为)

    /**
     * 在代理模式中表示真实行为
     */
    public interface IHttpProcessor {
    
        void post(String url, Map<String,Object> params,ICallBack iCallBack);
        void get(String url, Map<String,Object> params,ICallBack iCallBack);
    }
    
    /**
     * 网络访问成功失败的回调
     */
    interface ICallBack {
        void onSuccess(String result);
    
        void onFailure(String error);
    }
    

    第二步,实现卖房者(主要真实提供房子,但不提供卖房行为,具体要交给中介)

    真实提供房子:这句话就是具备有行为,但是自己不执行这个行为
    这里以Okhttp3网络访问为例子

    
    /**
     * 在代理模式中 表示真实提供者(必须具有目标行为能力)
     */
        public class OkhttpProcessor implements IHttpProcessor {
    
        public OkHttpClient mOkHttpClient;
        public Handler mHandler;
    
        public final static String TAG = "OkhttpProcessor";
    
        public OkhttpProcessor() {
            mOkHttpClient = new OkHttpClient();
            mHandler = new Handler();
        }
    
        @Override
        public void post(String url, Map<String, Object> params, final ICallBack iCallBack) {
            RequestBody requestBody = getRequestBody(params);
            Request build = new Request.Builder().post(requestBody).url(url).build();
            mOkHttpClient.newCall(build).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    Log.d(TAG, "onFailure: " + e.getMessage());
                }
    
                @Override
                public void onResponse(Call call, final Response response) throws IOException {
                    final boolean successful = response.isSuccessful();
                    solveRespone(response, successful, iCallBack);
    
                }
            });
        }
    
        /**
         * 处理响应体的结果
         * @param response 响应体
         * @param successful 成功
         * @param iCallBack  成功失败回调
         * @throws IOException
         */
        private void solveRespone(final Response response, final boolean successful, final ICallBack iCallBack) throws IOException {
            final String string = response.body().string();
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (successful) {
                        iCallBack.onSuccess(string);
                    } else {
                        iCallBack.onFailure(response.message());
                    }
                }
            });
        }
    
        /**
         * 得到一个请求体
         * @param params 参数集合
         * @return 拿到一个请求体
         */
        private RequestBody getRequestBody(Map<String, Object> params) {
            FormBody.Builder builder = new FormBody.Builder();
            for (Map.Entry<String, Object> objectEntry : params.entrySet()) {
                String key = objectEntry.getKey();
                builder.add(key, objectEntry.getValue().toString());
            }
            return builder.build();
        }
    
        @Override
        public void get(String url, Map<String, Object> params, final ICallBack iCallBack) {
            Request build = new Request.Builder().get().url(url).build();
            mOkHttpClient.newCall(build).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    Log.d(TAG, "onFailure: " + e.getMessage());
                }
    
                @Override
                public void onResponse(Call call, final Response response) throws IOException {
                    final boolean successful = response.isSuccessful();
                    solveRespone(response, successful, iCallBack);  //处理响应体的结果
                }
            });
        }
    }
    
    

    第三步.实现中介(也就是就代理行为,而自己不具有真实行为的对象)

    /**
     * 在代理模式中  处于中介 对于真实需求行为和真实行为提供者 进行集中代理
     */
    public class HttpHelper implements IHttpProcessor {
    
        private static IHttpProcessor mIHttpProcessor;
        private static HttpHelper instance;
        private Map<String, Object> mParams;
    
        public HttpHelper() {
            mParams = new HashMap<>();
        }
    
        public static HttpHelper getInstance() {
            if (instance == null) {
                synchronized (HttpHelper.class) {
                    if (instance == null) {
                        return instance = new HttpHelper();
                    }
                }
            }
            return instance;
        }
    
        public static void init(IHttpProcessor iHttpProcessor) {
            mIHttpProcessor = iHttpProcessor;
        }
    
       @Override
        public void post(String url, Map<String, Object> params, ICallBack iCallBack) {
            //事实上 这里应该去对url进行拼接
            mIHttpProcessor.post(url, params, iCallBack);
        }
    
        @Override
        public void get(String url, Map<String, Object> params, ICallBack iCallBack) {
            mIHttpProcessor.get(url, params, iCallBack);
        }
    }
    

    大概的内容我们写完了, 但是现在有一个问题,卖房的人不止一个,有可能有甲乙丙丁甚至更多,那如何实现呢?
    我贴一下用Volley 框架进行隔离的代码吧!

    /**
     * 每个具体的processor都需要实现该方法具体的网络请求访问方式
     */
    
    public class VolleyProcessor implements IHttpProcessor {
    
    
        public RequestQueue mRequestQueue = null;
    
        public VolleyProcessor(Context context) {
            mRequestQueue = Volley.newRequestQueue(context);
        }
    
        @Override
        public void post(String url, Map<String, Object> params, final ICallBack iCallBack) {
    
            StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    iCallBack.onSuccess(response);
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    iCallBack.onFailure(error.toString());
                }
            });
            mRequestQueue.add(stringRequest);
        }
    
        @Override
        public void get(String url, Map<String, Object> params, final ICallBack iCallBack) {
            StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    iCallBack.onSuccess(response);
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    iCallBack.onFailure(error.getMessage());
                }
            });
            mRequestQueue.add(stringRequest);
        }
    
    
    }
    

    因此,如果行为提供方(在这里我们说的行为是进行网络访问请求),okhttp3,volley都是提供网络访问请求的行为提供方,不再直接接触直接访问网络的逻辑,不再直接在P层或者说界面,而是通过中介类进行调用.


    代理模式讲到这里,不知道你是否对它熟悉了呢? 以上的代码是一些例子,还不完善.仅供各位参考.

    最后谢谢大家阅读本篇文章,如果你觉得文章对有所启发,或者对你帮助,请给我一颗红心吧!!

    相关文章

      网友评论

          本文标题:学习代理模式----实现快速切换网络访问框架

          本文链接:https://www.haomeiwen.com/subject/rthjdftx.html