Reading OkHttp source code in Android 2 (chain of responsibility model)

The blogger discovered a giant artificial intelligence learning website a few days ago. It is easy to understand and humorous. I can’t help but share it with everyone.
Click to jump to the tutorial

Android OkHttp source code reading detailed explanation 1

Looking at the OkHttp source code, I found that OkHttp uses the responsibility chain design pattern, so I need to learn the responsibility chain design pattern. Section 2
Response will eventually be returned
Response getResponseWithInterceptorChain() throws IOException {<!-- -->
    // Build a full stack of interceptors.
    List<Interceptor> interceptors = new ArrayList<>();
    interceptors.addAll(client.interceptors());
    interceptors.add(retryAndFollowUpInterceptor);
    interceptors.add(new BridgeInterceptor(client.cookieJar()));
    interceptors.add(new CacheInterceptor(client.internalCache()));
    interceptors.add(new ConnectInterceptor(client));
    if (!forWebSocket) {<!-- -->
      interceptors.addAll(client.networkInterceptors());
    }
    interceptors.add(new CallServerInterceptor(forWebSocket));

    Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,
        originalRequest, this, eventListener, client.connectTimeoutMillis(),
        client.readTimeoutMillis(), client.writeTimeoutMillis());

    return chain.proceed(originalRequest);
  }

Cases under the chain package Familiar with the chain of responsibility model
The case under the chain2 package corresponds to the responsibility chain mode getResponseWithInterceptorChain() in the OkHttp source code

Read the summary of OkHttp source code
1.OSI seven-layer model, TCP/IP reference model, HTTP format
2. We read the main process of OkHttp source code
3. We read the thread pool of OkHttp source code caching solution
4. We read the OkHttp source code and discovered the builder design pattern and chain of responsibility pattern.

1. First write a case to familiarize yourself with the chain of responsibility model

1. Define an abstract class BaseTask

public abstract class BaseTask {<!-- -->
    //Determine whether the current task node has the ability to execute
    private boolean isTask;


    public BaseTask(boolean isTask) {<!-- -->
        this.isTask = isTask;
    }

    //Execute the next node
    private BaseTask nextTask; //t2,t3

    //Add next node task
    public void addNextTask(BaseTask nextTask) {<!-- -->
        this.nextTask = nextTask;
    }

    //Let the child node tasks be completed
    public abstract void doActon();

    //action
    public void action() {<!-- --> //t1=false t2=false,t3=true
        if (isTask) {<!-- -->
            doActon(); //Execute the child node and the chain will be broken.
        } else {<!-- -->
            //Continue executing the next task node
            if (nextTask != null) {<!-- -->
                nextTask.action();
            }
        }
    }
}

2. Define four Task classes, all of which inherit from BaseTask. Only one is written here and the other three are the same.

public class Task1 extends BaseTask {<!-- -->
    public Task1(boolean isTask) {<!-- -->
        super(isTask);
    }

    @Override
    public void doActon() {<!-- -->
        //Execute child nodes
        System.out.println("Task1 task node one was executed");
    }
}

3. Define a Test class for testing

public class Test {<!-- -->
    public static void main(String[] args) {<!-- -->
        Task1 task1 = new Task1(false);
        Task2 task2 = new Task2(false);
        Task3 task3 = new Task3(true);
        Task4 task4 = new Task4(false);

        task1.addNextTask(task2);
        task2.addNextTask(task3);
        task3.addNextTask(task4);

        //Execute the first task node
        task1.action();
    }
}

Output result:

Task3 task node three was executed

2. Write a case to familiarize yourself with the chain of responsibility model, corresponding to the chain of responsibility model getResponseWithInterceptorChain() in the OkHttp source code

1. First define an interface

public interface IBaseTask {<!-- -->
    /**
     * @param isTask Whether the task node is executed by someone
     * @param iBaseTask next task node
     */
    void doRunAction(String isTask, IBaseTask iBaseTask);
}

2. Define a chain management class ChainManager

public class ChainManager implements IBaseTask {<!-- -->
    private List<IBaseTask> mIBaseTaskList = new ArrayList<>();
    private int index = 0;

    public void addTask(IBaseTask iBaseTask) {<!-- -->
        mIBaseTaskList.add(iBaseTask);
    }

    @Override
    public void doRunAction(String isTask, IBaseTask iBaseTask) {<!-- -->
        if (mIBaseTaskList.isEmpty()) {<!-- -->
            //throw an exception
            return;
        }
        if (index >= mIBaseTaskList.size()) {<!-- -->
            return;
        }
        IBaseTask iBaseTaskResult = mIBaseTaskList.get(index);//t1
        index + + ;
        iBaseTaskResult.doRunAction(isTask, iBaseTask);
    }
}

3. Define three Task1, Task2, and Task3

public class Task1 implements IBaseTask {<!-- -->
    @Override
    public void doRunAction(String isTask, IBaseTask iBaseTask) {<!-- -->
        if ("no".equals(isTask)) {<!-- -->
            System.out.println("Interceptor task node 1 processed...");
            return;
        } else {<!-- -->
            iBaseTask.doRunAction(isTask, iBaseTask);
        }
    }
}

public class Task2 implements IBaseTask {<!-- -->
    @Override
    public void doRunAction(String isTask, IBaseTask iBaseTask) {<!-- -->
        if ("ok".equals(isTask)) {<!-- -->
            System.out.println("Interceptor task node 2 processed...");
            return;
        } else {<!-- -->
            iBaseTask.doRunAction(isTask, iBaseTask);
        }
    }
}
public class Task3 implements IBaseTask {<!-- -->
    @Override
    public void doRunAction(String isTask, IBaseTask iBaseTask) {<!-- -->
        if ("no".equals(isTask)) {<!-- -->
            System.out.println("Interceptor task node 3 processed...");
            return;
        } else {<!-- -->
            iBaseTask.doRunAction(isTask, iBaseTask);
        }
    }
}

4. Define a Test class for testing

public class Test {<!-- -->
    public static void main(String[] args) {<!-- -->
        ChainManager chainManager = new ChainManager();
        chainManager.addTask(new Task1());
        chainManager.addTask(new Task2());
        chainManager.addTask(new Task3());
        chainManager.doRunAction("ok", chainManager);
    }
}

The output is as follows:

Interceptor task node 2 processed...