Six Basic Principles of Android Design Patterns

Single Responsibility Principle SRP

With respect to a class, there is only one cause for it to change

Open Closed Principle OCP

Changes are implemented by means of extensions, rather than by modifying existing codes. Try not to add new implementations through inheritance, etc.

Liskov Substitution Principle LSP

As long as the parent class can appear, the subclass can appear, mainly in the implementation and inheritance

Dependency Inversion Principle DIP

A specific form of decoupling in which high-level modules do not depend on low-level modules, and high-level modules do not depend on details but on abstractions

Interface Segregation Principle ISP

Let the client depend on as few interfaces as possible. Interface split, single interface

Demeter Principle LDP

The principle of least known, an object has the least knowledge about other objects

Practical application

Design a network request framework, the functions include: network request, cache, return data analysis, etc.

1. The first stage:

        All functions are written in Activity

  Problem: There is no design at all. There are too many duplicate codes when calling in multiple places. If you modify it, you need to modify the second stage in all places.

2. The second stage:

        Encapsulate the request into the tool class HttpUtils

  Problem: The HttpUtils class is too bloated and does too many things. Requests, caches, etc. are all coupled in this class, and the returned data analysis processing can only be processed by external callers, etc.

3. The third stage:

  1. Extract the cache function into SpHttpCache (currently the cache is only cached to sp) ( single responsibility principle )
  2. Create the HttpCallBack interface, directly operate the callback of the success or failure of the request, and put the processing of the returned result public event into the HttpUtils request, such as data analysis and compatibility of returned data in different formats

  Problem: Just encapsulate some common logic into a tool class, there is no scalability at all, the request codes are all crowded into one pile, there are too many call parameters, and more than a dozen parameters may need to be passed in to the construction method, such as request method and request parameters , timeout reconnection, timeout period, whether to support cookies, etc. If you need to expand the parameters, you need to add more constructors

4. The fourth stage:   

  1. In HttpUtils, modify the parameters to chain calls, call the parameters that the caller needs, and don’t call if they don’t need them
  2.     public static HttpUtils with(Context context){
            return new HttpUtils(context);
        }
    
        private HttpUtils(Context context) {
            mHttpRequest = new OKHttpRequest();
            mParams = new HashMap<>();
            this.mContext = context;
        }
    
        public HttpUtils get(){
            mType = TYPE_GET;
            return this;
        }
    
        public HttpUtils param(String key,Object value){
            mParams.put(key,value);
            return this;
        }
    
        public HttpUtils url(String url){
            this.mUrl = url;
            return this;
        }
    
        public <T> void request(final HttpCallBack<T> callback){
            // 在此做一些异常判断,如url校验等
            mHttpRequest.get(mContext,mUrl,mParams,callback,true);
        }
  3. Do parameter verification before requesting
  4. Encapsulate the request into the OKHttpRequest class ( single responsibility principle )

  Question: If you want to use other network requests, you can only modify the call of HttpUtils, or you can switch network requests at any time, how to deal with it

5. The fifth stage:   

  1. Create an IHttpRequest interface, and define methods such as get and post in the interface
  2. The OKHttpRequest request class implements the IHttpRequest interface interface
  3. Add an IHttpRequest parameter in HttpUtils, and the caller can pass in the subclass that implements the IHttpRequest interface through chain calls
    private IHttpRequest mHttpRequest;
    ……
    public HttpUtils httpRequest(IHttpRequest httpRequest){
        mHttpRequest = httpRequest;
        return this;
    }

    // 可在application设置默认请求
    public static void initHttpRequest(IHttpRequest httpRequest) {
        mInitHttpRequest = httpRequest;
    }


    public <T> void request(final HttpCallBack<T> callback){
        if(mHttpRequest == null){
            mHttpRequest = mInitHttpRequest;
        }
        // 异常判断
        mHttpRequest.get(mContext,mUrl,mParams,callback,true);
    }

    4. If you want to add a new network request, you only need to create a class that implements IHttpRequest, and call the httpRequest() method to set the required network request when calling

        Opening and closing principle: When new network requests need to be added, there is no need to modify the code of HttpUtils, only new classes need to be added, which is open for extension and closed for modification

         Liskov substitution principle: where the parent class IHttpRequest appears, the subclass OKHttpRequest can appear, HttpUtils.initHttpRequest(new OKHttpRequest());

         Dependency Inversion Principle: High-level HttpUtils do not depend on low-level details (OKHttpRequest), but on low-level abstractions (IHttpRequest)

        Dimiter principle: In MainActivity, use HttpUtils to make network requests. It doesn’t matter how it is implemented in it. You only know what parameters need to be passed and get the final result back. Don’t care about the rest

     5. The same is true for the cache class, memory cache, disk cache (database, hard disk)

        Frequently used interfaces can be cached in memory and disk, and infrequently used interfaces can be cached directly in disk

Guess you like

Origin blog.csdn.net/weixin_42277946/article/details/131031429