Responsibility chain mode (C language Implementation)

Source: Internet
Author: User

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-&GT;SUCC = NULL; return self;}    static void Concretehandleasetsuccessor (void *_self, void *_succ) {_concretehandlea *self = _self; SELF-&GT;SUCC = _SUCC;}    static void *concretehandleagetsuccessor (const void *_self) {const _concretehandlea *self = _self; return SELF-&GT;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-&GT;SUCC = NULL; return self;}    static void Concretehandlebsetsuccessor (void *_self, void *_succ) {_concretehandleb *self = _self; SELF-&GT;SUCC = _SUCC;}    static void *concretehandlebgetsuccessor (const void *_self) {const _concretehandleb *self = _self; return SELF-&GT;SUCC;} static void Concretehandlebhandlerequest (const void *_self, int request) {if (Request >= && request &lt ;    ) {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-&GT;SUCC = NULL; return self;}    static void Concretehandlecsetsuccessor (void *_self, void *_succ) {_concretehandlec *self = _self; SELF-&GT;SUCC = _SUCC;}    static void *concretehandlecgetsuccessor (const void *_self) {const _concretehandlec *self = _self; return SELF-&GT;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)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.