I. Overview
Responsibility Chain Mode:
Enables multiple objects to have the opportunity to process requests, thus avoiding the coupling between the sender and receiver of the request. Link the objects together and pass the request along the chain until an object handles it.
Two. An example
Employees ask for a raise
The company's managers have a total of three: General manager, director, manager, if an employee asks for a raise, should apply to the Supervisor's manager, if the number of raises in the manager's authority, then the manager can directly approve, otherwise the application will be submitted to the Director. The Director also handles the same, and the general manager can handle all requests. This is the typical chain of responsibility pattern, where the processing of the request forms a chain until an object processes the request.
The structure diagram is as follows:
Assume:
The manager can handle the salary range in: 0~500
The director can handle the salary range at: 500~1000
The general manager can handle the range of the salary in: 1000~2000
The code is as follows:
AbstractClass.h
#ifndef abstractclass_h#define abstractclass_h#include <stdlib.h> #include <stdarg.h>typedef struct { size_t size; void* (*ctor) (void *_self, va_list *params); void* (*dtor) (void *_self);} AbstractClass; #endif
Handle.h
#ifndef handle_h#define handle_h#include <stdlib.h> #include <stdarg.h>typedef struct { size_t size; void* (*ctor) (void *_self, va_list *params); void* (*dtor) (void *_self); void (*setsuccessor) (void *_self, void *succ); void * (*getsuccessor) (const void *_self); void (*handlerequest) (const void *_self, int request);} Handle; #endif
ConcreteHandleA.h
#ifndef concretehandlea_h#define concretehandlea_htypedef struct { const void *_; void *succ;} _concretehandlea;extern const void *concretehandlea; #endif
Concretehandlea.c
#include "handle.h" #include "concreteHandleA.h" #include <stdlib.h> #include <stdio.h>static void * Concretehandleactor (void *_self, va_list *params) {_concretehandlea *self = _self; return self;} static void *concretehandleadtor (void *_self) {_concretehandlea *self = _self; SELF->SUCC = NULL; return self;} static void Concretehandleasetsuccessor (void *_self, void *_succ) {_concretehandlea *self = _self; SELF->SUCC = _SUCC;} static void *concretehandleagetsuccessor (const void *_self) {const _concretehandlea *self = _self; return SELF->SUCC;} static void Concretehandleahandlerequest (const void *_self, int request) {if (Request >= 0 && Request < {fprintf (stdout, "Concretehandlea deal with:%d\n", request); } else if (Concretehandleagetsuccessor (_self) = NULL) {Const HANDLE * Const *SUCC = Concretehandleagetsuccessor (_ self); (*SUCC)->handlerequest (succ, request); } else {fprintf (stDerr, "Can ' t deal with:%d\n", request); }}static Const Handle _concretehandlea = {sizeof (_concretehandlea), Concretehandleactor, Concretehandleadtor, Concretehandleasetsuccessor, Concretehandleagetsuccessor, Concretehandleahandlerequest};const void *ConcreteHandle A = &_concreteHandleA;
concreteHandleB.h
#ifndef concretehandleb_h#define concretehandleb_htypedef struct { const void *_; void *succ;} _concretehandleb;extern const void *concretehandleb; #endif
Concretehandleb.c
/p>
#include "handle.h" #include "concreteHandleB.h" #include <stdlib.h> #include <stdio.h>static void * Concretehandlebctor (void *_self, va_list *params) {_concretehandleb *self = _self; return self;} static void *concretehandlebdtor (void *_self) {_concretehandleb *self = _self; SELF->SUCC = NULL; return self;} static void Concretehandlebsetsuccessor (void *_self, void *_succ) {_concretehandleb *self = _self; SELF->SUCC = _SUCC;} static void *concretehandlebgetsuccessor (const void *_self) {const _concretehandleb *self = _self; return SELF->SUCC;} static void Concretehandlebhandlerequest (const void *_self, int request) {if (Request >= && request < ; ) {fprintf (stdout, "Concretehandleb deal with:%d\n", request); } else if (Concretehandlebgetsuccessor (_self) = NULL) {Const HANDLE * Const *SUCC = Concretehandlebgetsuccessor (_ self); (*SUCC)->handlerequest (succ, request); } else {fprintf(stderr, "Can ' t deal with:%d\n", request); }}static Const Handle _concretehandleb = {sizeof (_concretehandleb), Concretehandlebctor, Concretehandlebdtor, Concretehandlebsetsuccessor, Concretehandlebgetsuccessor, Concretehandlebhandlerequest};const void *ConcreteHandle B = &_concreteHandleB;
ConcreteHandleC.h
#ifndef concretehandlec_h#define concretehandlec_htypedef struct { const void *_; void *succ;} _concretehandlec;extern const void *concretehandlec; #endif
Concretehandlec.c
#include "handle.h" #include "concreteHandleC.h" #include <stdlib.h> #include <stdio.h>static void * Concretehandlecctor (void *_self, va_list *params) {_concretehandlec *self = _self; return self;} static void *concretehandlecdtor (void *_self) {_concretehandlec *self = _self; SELF->SUCC = NULL; return self;} static void Concretehandlecsetsuccessor (void *_self, void *_succ) {_concretehandlec *self = _self; SELF->SUCC = _SUCC;} static void *concretehandlecgetsuccessor (const void *_self) {const _concretehandlec *self = _self; return SELF->SUCC;} static void Concretehandlechandlerequest (const void *_self, int request) {if (Request >= && request &L T (a) {fprintf (stdout, "Concretehandlec deal with:%d\n", request); } else if (Concretehandlecgetsuccessor (_self) = NULL) {Const HANDLE * Const *SUCC = Concretehandlecgetsuccessor (_ self); (*SUCC)->handlerequest (succ, request); } else {FprintF (stderr, "Can ' t deal with:%d\n", request); }}static Const Handle _concretehandlec = {sizeof (_CONCRETEHANDLEC), Concretehandlecctor, Concretehandlecdtor, Concretehandlecsetsuccessor, Concretehandlecgetsuccessor, Concretehandlechandlerequest};const void *ConcreteHandle C = &_concreteHandleC;
New.h
#ifndef new_h#define new_hvoid *new (const void *_class, ...); void Delete (void *_class), void setsuccessor (void *_handle, void *_succ), void HandleRequest (void *_handle, int request); endif
New.c
#include "new.h" #include "abstractClass.h" #include "handle.h" #include <stdarg.h> #include <stdlib.h># Include <assert.h> #include <stdio.h>void *new (const void *_class, ...) {Const AbstractClass *class = _class; void *p = Calloc (1, class->size); ASSERT (P); * (CONST ABSTRACTCLASS * *) p = class; if (class->ctor) {va_list params; Va_start (params, _class); p = class->ctor (P,¶MS); Va_end (params); } return p;} void Delete (void *_class) {const AbstractClass **class = _class; if (_class && *class && (*class)->dtor) {_class = (*class)->dtor (_class); } free (_class);} void Setsuccessor (void *_handle, void *_succ) {handle **handle = _handle; if (_handle && *handle && (*handle)->setsuccessor) {(*handle)->setsuccessor (_handle, _SUCC); }}void handlerequest (void *_handle, int request) {handle **handle = _handle; if (_handle &&amP *handle && (*handle)->handlerequest) {(*handle)->handlerequest (_handle, request); }}
Main.c
#include "new.h" #include "concreteHandleA.h" #include "concreteHandleB.h" #include "concreteHandleC.h" int main (int ARGC, Char *argv[]) { void *h1 = New (Concretehandlea); void *h2 = New (Concretehandleb); void *h3 = New (Concretehandlec); Setsuccessor (H1, H2); Setsuccessor (H2, H3); HandleRequest (H1); HandleRequest (H1, +); HandleRequest (H1); HandleRequest (H1, N); Delete (H1); Delete (H2); Delete (H3); return 0;}
Image source: http://blog.csdn.net/hmsiwtv/article/details/9627307
Responsibility chain mode (C language Implementation)