Project architecture evolution - from the facade proxy mode to mode

We use the project evolved ways to look at how to write the original code from the very beginning, serious coupling this way the code reusability is not at all, if we want to add some parameters need to have a unified request to modify it again in each place, the workload is huge. So we naturally think of how certain packages on this basis, so that one use of a unified request, without duplication of code written in multiple passes. And then later we have more demand switching network library, then, is how do use a proxy mode can switch network library. These three levels, take a look at the evolution of better wording. For simplicity, we use the tripartite library volley as a network request.

Project code here: https://github.com/buder-cp/DesignPattern/tree/master/FacadeToAgentMode

Version 1:

Initially we wrote a network request if there has been no package, is like the following:

@Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.http_request) {
            StringRequest stringRequest = new StringRequest(Request.Method.GET,
                    URL, new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    try {
                        JSONObject obj = new JSONObject(response);
                        String source = obj.getString("source");
                        Toast.makeText(MainActivity.this, source, Toast.LENGTH_SHORT).show();

                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {

                }
            });

            mQueue.add(stringRequest);
        }
    }

The need to use the local network requests, using the most direct way to the original request, the disadvantage of this approach is very clear, first: for example, I have 100 projects in place requires a network request, the original wording of the request StringRequest need to write a hundred times, if one day need to harmonize addition request message header information, and also modified one by one in 100 places; second: network request logic and UI coupling, we need to try to make the separation of logic and UI, this booing, direct mixing to go together, if the business complex, then the amount of code in a file will be overwhelmed. So many shortcomings, then we naturally think, need to write a single network request class to manage the network request then the following is our 2.0 version facade pattern:

Version two: using the facade pattern

public class FacadeNetWork {

    public interface Callback<T> {
        void onSuccess(T respone);
        void onFailed(String failed);
    }

    private static RequestQueue mQueue;
    private static FacadeNetWork mInstance;
    private Context mContext;

    private FacadeNetWork(Context context) {
        mContext = context;
        mQueue = Volley.newRequestQueue(context);
    }

    public static FacadeNetWork getInstance(Context context) {
        if (mInstance == null) {
            synchronized (FacadeNetWork.class) {
                if (mInstance == null) {
                    mInstance = new FacadeNetWork(context);
                }
            }
        }
        return mInstance;
    }
    public void get(final String url, final Callback callback) {
        StringRequest stringRequest = new StringRequest(Request.Method.GET,
                url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                try {
                    JSONObject obj = new JSONObject(response);
                    String source = obj.getString("source");
                    callback.onSuccess(source);

                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                callback.onFailed(error.toString());
            }
        });

        mQueue.add(stringRequest);
    }
}

Singleton provide external web service call request, the following get, post, etc. unified network requests we write, then we will be very convenient to call, as follows:

FacadeNetWork facadeNetWork = FacadeNetWork.getInstance(this);
            facadeNetWork.get(URL, new FacadeNetWork.Callback() {
                @Override
                public void onSuccess(Object respone) {
                    Toast.makeText(MainActivity.this, respone.toString(), Toast.LENGTH_SHORT).show();
                }

                @Override
                public void onFailed(String failed) {

                }
            });

Actual projects, most of us are doing so, but still not good enough, if one day our network requests the library has changed, you need to use Retrofit, then, at this time we need to modify our network management class FacadeNetWork request inside request code, which does not comply with the principle of modified closed, because we write the class is not allowed to change, the reason is that we need to change the extension is not good enough, then we use a proxy mode to enhance the scalability of our architecture,

Version three: use a proxy mode (Proxy is a Erdaofanzi, left hand into his right hand out, we are looking for agents to provide services, agents can provide real service to find the class, so we need to know the name of the service we need, this is the need for agents and service names service class to implement a unified interface, the following steps)

Step one: real proxy class and implementation class of service, maybe the name is certainly the same, the name of the service is agreed in advance, here we use the interface to indicate, for example, need to get service requests:

Proxy class and real class unified service name:

public interface IHttp {
    void get(String url, ICallBack callBack);
}

Step two: real class service certainly needs to implement this service, we can have multiple class real implementation services, and here we use Volley OKHttp example:

volley implementation class:

public class VolleyModel implements IHttp{

    private static RequestQueue mQueue;
    private static VolleyModel mInstance;
    private Context mContext;

    private VolleyModel(Context context) {
        mContext = context;
        mQueue = Volley.newRequestQueue(context);
    }

    public static VolleyModel getInstance(Context context) {
        if (mInstance == null) {
            synchronized (VolleyModel.class) {
                if (mInstance == null) {
                    mInstance = new VolleyModel(context);
                }
            }
        }
        return mInstance;
    }

    @Override
    public void get(String url, final ICallBack callBack) {
        StringRequest stringRequest = new StringRequest(Request.Method.GET,
                url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                try {
                    JSONObject obj = new JSONObject(response);
                    String source = obj.getString("source");
                    callBack.onSuccess(source);

                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                callBack.onFailed(error.toString());
            }
        });

        mQueue.add(stringRequest);
    }
}

OKHttp implementation class:

public class OkHttpModel implements IHttp{

    private static RequestQueue mQueue;
    private static OkHttpModel mInstance;
    private Context mContext;

    private OkHttpModel(Context context) {
        mContext = context;
        mQueue = Volley.newRequestQueue(context);
    }


    @Override
    public void get(String url, final ICallBack callBack) {
        StringRequest stringRequest = new StringRequest(Request.Method.GET,
                url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                try {
                    JSONObject obj = new JSONObject(response);
                    String source = obj.getString("source");
                    callBack.onSuccess(source);

                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                callBack.onFailed(error.toString());
            }
        });

        mQueue.add(stringRequest);
    }
}

Step three: We need to find an agent, this Erdaofanzi, why did he need to implement this interface, let's say, the agent is a forward, we know ahead of our own needs is what services, the service name in proxy and implementation class it's the same

public class HttpProxy implements IHttp {

    private static IHttp mHttp = null;

    private static HttpProxy mInstance;

    private HttpProxy() {
        mInstance = this;
    }

    public static HttpProxy obtain() {
        if (mInstance == null) {
            synchronized (OkHttpModel.class) {
                if (mInstance == null) {
                    mInstance = new HttpProxy();
                }
            }
        }
        return mInstance;
    }

    public static void init(IHttp http) {
        mHttp = http;
    }

    /**
     * 代理的扩展属性和方法增强性
     * @param url
     * @param callBack
     */
    @Override
    public void get(String url, ICallBack callBack) {
        /**
         * 代理类的作用:
         * 1.可以在调用真正服务的类之前,做一些自己额外的任务,例如收取手续费,请求重定向等等;
         * 代理类可以实现拦截方法,修改原方法的参数和返回值,满足了代理自身需求和目的,也就
         * 是代理的方法增强性。
         * 2.内部对象因为某个原因换了个名或者换了个方法字段等等,那对访问者来说一点不影响,
         * 因为他拿到的只是代理类而已,从而使该访问对象具有高扩展性
         */
        mHttp.get(url, callBack);
    }
}

Note the use of multi-state, who registered the init () function object, we use the framework which network services, network switches framework as follows:

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        HttpProxy.init(VolleyModel.getInstance(getApplicationContext()));
//        HttpProxy.init(OkHttpModel.getInstance(getApplicationContext()));
    }
}

 

Item code: https://github.com/buder-cp/DesignPattern/tree/master/FacadeToAgentMode

Guess you like

Origin blog.csdn.net/cpcpcp123/article/details/103834135
Recommended