C/Java/JS/Go/Python/TS different language implementation

Introduction

Chain of Responsibility Pattern (Chain of Responsibility Pattern) is a behavioral design pattern, also known as chain of responsibility pattern, chain of command pattern. This pattern creates a chain of receiver objects for requests, allowing you to send requests down a chain of handlers, each of which can either process the request or pass it on to the next handler in the chain.

The Chain of Responsibility pattern can be used when a program needs to process multiple types of requests in different ways, and the request type and order are unknown, or when multiple processes must be performed in sequence. Or use this pattern if the required processing and its order must be changed at runtime.

effect

  1. To avoid the coupling of the request sender and the receiver, the client only needs to send the request to the chain, and does not need to care about the processing details of the request and the delivery of the request.
  2. By changing the members in the chain or mobilizing their order, it is allowed to dynamically add or delete responsibilities.

Implementation steps

  1. Create an abstract processor class for processor inheritance.
  2. The abstract processor class can organize the subclasses into chains arbitrarily for easy calling.
  3. Create multiple processors that do not interfere with each other, and implement the next method of the abstract class to continuously perform chain checks.

UML

java code

abstract event handling class

// All processing in AbstractHandler.java becomes a chain, which can be interactively intervened and dynamically combined 
public abstract class AbstractHandler { 
   // Form a responsibility chain 
   private AbstractHandler next; 

   // Create a call chain, pass in multiple handlers, form a chain in order, and return The first handler 
   public static AbstractHandler link(AbstractHandler first, AbstractHandler... chain) { 
      AbstractHandler head = first; 
      for (AbstractHandler handler : chain) { 
         head.next = handler; 
         head = handler; 
      } 
      return first; 
   } 

   // sub The check method that the class needs to implement 
   public abstract boolean check(int uid); 

   // Continue to the next check 
   protected boolean checkNext(int uid) { 
      if (next == null) {  
         return true;
      }
      return next.check(uid);
   }
}

Different events, can be multiple, not related to each other

```java 
// AuthHandler.java permission check class 
public class AuthHandler extends AbstractHandler { 
    // If the check fails, return failure, otherwise continue to the next check 
    public boolean check(int uid) { 
      System.out.println(this.getClass ().getName() + "::check() [uid = " + uid + "]"); 
      if (uid % 2 == 0) { 
          return false; 
      } 
      return checkNext(uid); 
  } 
} 
``` 

```java 
// RequestHandler.java checks whether the request is safe and legal 
public class RequestHandler extends AbstractHandler { 
    // If the check fails, return failure, otherwise continue to the next check 
    public boolean check(int uid) {  
      System.out.println(this .getClass().getName() + "::check() [uid = " + uid + "]");
      if (uid % 1 != 0) { 
          return false; 
      } 
      return checkNext(uid); 
  } 
} 
``` 

```java 
// UserHandler.java Basic user information check class 
public class UserHandler extends AbstractHandler { 
    // Return failure if the check fails , otherwise continue to the next check 
    public boolean check(int uid) { 
        System.out.println(this.getClass().getName() + "::check() [uid = " + uid + "]"); 
        if ( uid % 3 == 0) { 
            return false; 
        } 
        return checkNext(uid); 
    } 
} 
```

test call

    /** 
     * The core of the chain of responsibility model is to create a call processing chain, each processing chain implements the next method of the abstract class, so that various inspection behaviors can be organized arbitrarily. 
     * By changing the members in the chain or mobilizing their order, it is allowed to dynamically add or delete responsibilities, so as to realize on-demand organization. 
     */ 

    // The responsibility chain can be organized arbitrarily, and the sequence can be used according to the needs. 
    AbstractHandler handler1 = AbstractHandler.link( 
        new RequestHandler(), 
        new UserHandler(), 
        new AuthHandler()); 

    System.out.println("handler1.check(1001 )Start"); 
    handler1.check(1001); 
    System.out.println("handler1.check(1002)Start"); 
    handler1.check(1002); // You can organize the chain of responsibility arbitrarily, and the sequence can come to 
    AbstractHandler 

    as needed handler2 = AbstractHandler. link( 
        new AuthHandler(), 
        new RequestHandler(), 
        new UserHandler());

    System.out.println("handler2.check(1001) start"); 
    handler2.check(1001); 
    System.out.println("handler2.check(1002) start"); 
    handler2.check(1002);

C language code

func.h header file function

#include <stdio.h> 
#include <stdlib.h> 
#include <stdbool.h> 

// define general handler 
typedef struct Handler 
{ 
    char name[50]; 
    // handler chain pointer 
    struct Handler *next; 
    // structure The internal check_handler function is for each handler to implement independently 
    bool (*check_handler)(struct Handler *, int); 
} Handler; 

// Create a handler call chain and create Handlers one by one 
*link_handler(Handler *handler, Handler *next); 

// The two methods of creating a chain handler have the same function, and multiple parameters can be passed in. 
Handler *make_handler_chain_count(int lenght, ...); 
Handler *make_handler_chain(Handler *handler, ...); 

// Check the handler general function 
bool check_handler_start(Handler *handler, int param); 


// define permission check handler 
typedef struct AuthHandler 
{
    char name[50];
    Handler *next;
    bool (*check_handler)(struct Handler *, int);
} AuthHandler;

// 创建AuthHandler
AuthHandler *create_auth_handler(char *name);

// 定义请求检查handler
typedef struct RequestHandler
{
    char name[50];
    Handler *next;
    bool (*check_handler)(struct Handler *, int);
} RequestHandler;

// 创建RequestHandler
RequestHandler *create_request_handler(char *name);

// 定义用户检查handler
typedef struct UserHandler
{
    char name[50];
    Handler *next;
    bool (*check_handler)(struct Handler *, int);
} UserHandler;

// 创建UserHandler
UserHandler *create_user_handler(char *name);

Unified Event Handling

// handler.c basic event 
#include <stdio.h> 
#include <stdlib.h> 
#include <stdarg.h> 
#include "func.h" 

// Create a call chain, form a chain in order, and return the first one handler 
Handler *link_handler(Handler *handler, Handler *next) 
{ 
  handler->next = next; 
  return handler; 
} 

// Create a call chain with variable parameters, the first parameter is the number of handlers, followed by multiple handlers 
Handler *make_handler_chain_count (int lenght, ...) 
{ 
  va_list args; 
  va_start(args, lenght); 
  // Take out the first handler 
  Handler *first = va_arg(args, Handler *); 
  Handler *head = first; 
  // Add handler to Next, form a chain, the total length minus the first 
  for (int i = 0; i < lenght - 1; i++) 
  {
    head->next = va_arg(args, Handler *); 
    head = head->next; 
bool check_handler_start(Handler *handler , int param) 
{ 
  }
  va_end(args); 
  return first; 
} 

// Create a call chain with variable parameters, the first parameter is the number of handlers, followed by multiple handlers, and the last one passes NULL 
Handler *make_handler_chain(Handler *first, ...) 
{ 
  va_list args; 
  va_start(args, first); 
  Handler *head = first; 
  // append handler to next, end with NULL 
  while (head != NULL) 
  { 
    head->next = va_arg(args, Handler *); 
    head = head->next; 
  } 
  va_end(args); 
  return first; 
} 

// separate handler check start function 
  return handler->check_handler(handler, param); 
}

Different events, can be multiple, not related to each other

```c 
// auth_handler.c permission check class 
#include <string.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include "func.h" 

/* AuthHandler check function implementation */ 
bool auth_handler_check (Handler *handler, int param) 
{ 
    printf("\r\n auth_handler_check: [handler.name = %s param = %d]", handler->name, param); AuthHandler 
    *auth_handler = (AuthHandler *)handler; 
    // Here is the judgment condition. If there is an error, the call chain will be terminated and false will be returned 
    if (param % 2 == 0) 
    { 
        printf("\r\n auth_handler_check: error[ %d %s 2 ] == 0", param, "%"); 
        return false; 
    } 
    // call the next step by next check 
    if (handler->next != NULL) 
    {
        return auth_handler->next->check_handler(handler->next, param); 
    } 
    return true; 
} 

/* Create a specific handler function */ 
AuthHandler *create_auth_handler(char *name) 
{ 
    AuthHandler *handler = (AuthHandler *)malloc (sizeof(AuthHandler)); 
    strncpy(handler->name, name, 50); 
    // Assign the check_handler function of the handler to the specified function, which is convenient for checking and processing 
    handler->check_handler = &auth_handler_check; 
    handler->next = NULL; 
    return handler ; 
} 
``` 

```c 
// request_handler.c check whether the request is safe and legal 
#include <string.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include "func.h"

/* RequestHandler check function implementation */
bool request_handler_check(Handler *handler, int param) 
{ 
  printf("\r\n request_handler_check: [handler.name = %s param = %d]", handler->name, param); RequestHandler 
  *request_handler = (RequestHandler *) handler; 
  // Here is the judgment condition, if an error occurs, the call chain will be terminated and false will be returned 
  if (param % 5 == 0) 
  { 
    printf("\r\n request_handler_check: error[ %d %s 5 ] == 0", param, "%"); 
    return false; 
  } 
  // Call the next check by next 
  if (handler->next != NULL) 
  { 
    return request_handler->next->check_handler(handler->next, param); 
  } 
  return true ;
} 

/* Create a specific handler function */ 
RequestHandler *create_request_handler(char *name) 
{
  RequestHandler *handler = (RequestHandler *)malloc(sizeof(RequestHandler)); 
  strncpy(handler->name, name, 50); 
  // Assign the check_handler function of the handler to the specified function, which is convenient for checking and processing 
  handler->check_handler = &request_handler_check; 
  handler->next = NULL; 
  return handler; 
} 
``` 

```c 
// user_handler.c Basic user information check class 
#include <string.h> 
#include <stdio.h> 
#include <stdlib.h> 
# include "func.h" 

/* UserHandler check_handler function implementation */ 
bool user_handler_check(Handler *handler, int param) 
{ 
  printf("\r\n user_handler_check: [handler.name = %s param = %d]", handler- >name, param);
  UserHandler *user_handler = (UserHandler *)handler;
  // Here is the judgment condition. If there is an error, the call chain will be terminated and false will be returned
  if (param % 3 == 0) 
  { 
    printf("\r\n user_handler_check: error[ %d %s 3 ] == 0", param, "%"); 
    return false; 
  } 
  // call the next step by next Check 
  if (handler->next != NULL) 
  { 
    return user_handler->next->check_handler(handler->next, param); 
  } 
  return true; 
} 

/* Function to create a specific handler*/ 
UserHandler *create_user_handler(char * name) 
{ 
  UserHandler *handler = (UserHandler *)malloc(sizeof(UserHandler)); 
  strncpy(handler->name, name, 50); 
  // Assign the check_handler function of the handler to the specified function, which is convenient for checking and processing 
  handler->check_handler = &user_handler_check; 
  handler->next = NULL; 
  return handler;
}
```

test call

#include <stdio.h> 
#include <stdlib.h> 
#include <stdbool.h> 
#include "../src/func.h" 

int main(void) 
{ 
    /** 
     * The core of the chain of responsibility model is to create a Call the processing chain, and each processing chain implements the next method of the abstract class, so that various inspection behaviors can be organized arbitrarily. 
     * By changing the members in the chain or mobilizing their order, it is allowed to dynamically add or delete responsibilities, so as to realize on-demand organization. 
     */ 

    // Create a set of hanler 
    RequestHandler *request_handler = create_request_handler("request_handler_01"); 
    UserHandler *user_handler = create_user_handler("user_handler_02"); 
    AuthHandler *auth_handler = create_auth_handler("auth_handler_03"); 
    printf ("Create handler:\r\ n %s %s %s", request_handler->name, user_handler->name, auth_handler->name);
 
    // Link handlers one by one into a chain of responsibility
    link_handler((Handler *)user_handler, (Handler *)auth_handler); 

    printf("\r\nCreate responsibility chain:\r\n"); 
    Handler *handler_cur = (Handler *)request_handler; 
    while (handler_cur != NULL) 
    { 
        printf(" -> %s", handler_cur->name); 
        handler_cur = handler_cur->next; 
    } 

    // start checking from any handler 
    // printf("\r\ncheck_handler_start check:"); 
    // check_handler_start(( Handler *)request_handler, 666); 
 
    // start 
    printf("\r\nstart checking:"); 
    bool result1 = request_handler->check_handler( (Handler *)request_handler, 666);
    printf("\r\nExecution result: %s \r\n", result1 ? "true" : "false"); / 

    * Release memory*/ 
    free(handler_cur); 
    free( request_handler); 
    free(auth_handler); 
    free(user_handler);

    /*** ========Splitting line============= ***/ 
    printf("\r\n========= =====\r\n"); 

    /* Create a set of hanler */ 
    RequestHandler *request_handler2 = create_request_handler("request_handler_101"); 
    UserHandler *user_handler2 = create_user_handler("user_handler_102"); 
    AuthHandler *auth_handler2 = create_auth_handler( "auth_handler_103 "); 
    printf("\r\nCreate handler:\r\n %s %s %s", request_handler2->name, user_handler2->name, auth_handler2->name);

    // Link the handler as a responsibility chain at one time, pass in multiple handlers, the first parameter is the quantity
    Handler *handler2 = make_handler_chain_count(3, auth_handler2, request_handler2, user_handler2); 
    printf("\r\nCreate responsibility chain:\r\n"); 
    Handler *handler_cur2 = (Handler *)handler2; 
    while (handler_cur2 != NULL) 
    { 
        printf(" -> %s", handler_cur2->name); 
        handler_cur2 = handler_cur2->next; 
    } 

    printf("\r\nStart inspection:");
    // Call the general inspection function to start
    bool result2 = check_handler_start(handler2, 777); 
    printf("\r\nExecution result: %s \r\n ", result2 ? "true" : "false"); 

    /* release memory*/ 
    free(handler_cur2); 
    free(request_handler2); 
    free(auth_handler2); 
    free(user_handler2); 

    /*** ======= =Separation line============ ***/ 
    printf("\r\n=============\r\n");
    /* Create another group of hanlers */ 
    RequestHandler *request_handler3 = create_request_handler("request_handler_201"); 
    UserHandler *user_handler3 = create_user_handler("user_handler_202");  
    AuthHandler *auth_handler3 = create_auth_handler("auth_handler_203" ); 
    printf("\r\nCreate handler:\r\ n %s %s %s", request_handler3->name, user_handler3->name, auth_handler3->name);
    // Link the handler as a responsibility chain at one time, pass in multiple handlers, the last The parameter is NULL 
    Handler *handler3 = make_handler_chain((Handler *)auth_handler3, user_handler3, request_handler3, NULL); 
    Handler *handler_cur3 = (Handler *)handler3; 
    printf("\r\nCreate responsibility chain:\r\n"); 
    while (handler_cur3 != NULL) 
    { 
        printf(" -> %s", handler_cur3->name); 
        handler_cur3 = handler_cur3->next; 
    } 
    printf("\r\nStart checking:"); 
    bool result3 = check_handler_start(handler3 , 167);
    printf("\r\nExecution result: %s \r\n", result3 ? "true" : "false"); /* Release memory*/ free(handler_cur3); free(request_handler3); free 

    ( 
    auth_handler3 
    ) 
    ; 
    free(user_handler3); 

    return 0; 
}

Guess you like

Origin blog.csdn.net/sinat_40572875/article/details/129758234