First, what is the responsibility chain model

The chain of responsibility pattern is one in which a request needs to be processed by multiple objects to avoid coupling between the sender and receiver of the request. Connect the objects into a chain and pass the request along the chain until an object handles it.

Roles in the chain of responsibility model: sender and receiver

The process of chain of responsibility mode:

  1. The sender knows the first recipient in the chain, to whom it makes a request
  2. Each recipient analyzes the request and either processes it or passes it on
  3. Each recipient knows only one other object, its next object
  4. If there are no recipients to process the request, it will go off the chain, and different implementations will react to this differently

Second, scene simulation

Currently has A development task, for example, the project manager (the sender) to assign A task to the developer (receiver), but the project manager is don’t know which developers can handle this task, assume that there are three developers A/B/C, A, found that after receiving task can’t handle this task will be down to the development of B, if B can’t handle will continue down to the C, So one layer passes on, forming a chain.

Three, the traditional way to achieve

// Task class (sender)
class Assign {
    constructor(task) {
        // Task name
        this.task = task
    }
}

// The class that receives the task
class WorkFlow {
    constructor(assign) {
        / / the sender
        this.assign = assign
    }
    handler(executorArr) {
        // Loop through the handler array to find which handler can do the task
        executorArr.forEach(item= > {
            if (this.assign.task == item.task) {
                return item.start()
            }
        })
        return; }}// Handler (receiver)
class Executor {
    constructor(name, task) {
        // Recipient name
        this.name = name
        // A task that the receiver can handle
        this.task = task
    }
    // Go to work
    start() {
        console.log(`The ${this.name}To do:The ${this.task}`)}}// instantiate the processing object
const C = new Executor('Cathy'.'SQL Optimization Task ')
const B = new Executor('bill'.'PHP Development Task ')
const A = new Executor('Joe'.'javascript Development Task ')

// Instantiate the task object
// The sender assigns a javascript development task
const assign = new Assign('SQL Optimization Task ')

// instantiate the receiving task class and pass the task down
const workflow = new WorkFlow(assign)
workflow.handler([A, B, C])
Copy the code

4. Realization of responsibility chain mode

// Task class (sender)
class Assign {
    constructor(task) {
        // Task name
        this.task = task
    }
}

// The class that receives the task
class WorkFlow {
    constructor(assign) {
        / / the sender
        this.assign = assign
    }
    // Process the receiving object and pass it to the next receiving object
    handler(executor) {
        // If the first handler can handle it, process the task directly
        if (this.assign.task == executor.task) {
            return executor.start()
        } else {
            // Otherwise, pass to the next handler
            this.handler(executor.successtor)
        }
        // If none of the handlers can handle it, return null
        return; }}// Handler (receiver)
class Executor {
    constructor(name, task, successtor) {
        // Recipient name
        this.name = name
        // A task that the receiver can handle
        this.task = task
        // A reference to the next handler
        this.successtor = successtor
    }
    // Go to work
    start() {
        console.log(`The ${this.name}To do:The ${this.task}`)}}// instantiate the processing object
const C = new Executor('Cathy'.'SQL Optimization Task ')
const B = new Executor('bill'.'PHP Development Task ', C)
const A = new Executor('Joe'.'javascript Development Task ', B)

// Instantiate the task object
// The sender assigns a javascript development task
const assign = new Assign('javascript Development Task ')

// instantiate the receiving task class and pass the task down
const workflow = new WorkFlow(assign)
workflow.handler(A)
Copy the code

Five, the summary

Usage scenario: After the above examples, we found that the chain of responsibility mode is suitable for cases where a task requires multiple objects to complete processing or where the code has many IF-else judgments, such as OA event approval, assignment of development tasks, etc.

Pros and cons: Reduced coupling between sender and receiver of request, clear division of labor, cleaner code. But at the same time, it needs to be passed down layer by layer to find the recipient who can handle the task. All the decision conditions need to be executed once. When the chain is too long, there may be performance problems.