• 设计模式之责任链模式20170717


    行为型设计模式之责任链模式:

    一、含义

    责任链模式的核心在"链"上,"链"是由多个处理者(对象)组成的,由这条链传递请求,直到有对象处理它为止(在链中决定谁来处理这个请求),并返回相应的结果

    二、代码说明

    1.主要有两个角色

    1)处理者

    它能够对请求做出处理(请求得到处理则直接返回,否则传到下一个处理者),设置下一个处理者(这两个操作可以抽象出来),

    同时每个处理者都有一个相应的处理级别,以及具体的处理操作(父类实现请求传递,子类实现请求处理)

    2)被处理者(请求者)

    主要包括请求以及这个请求对应的处理者级别

    2.在用C实现过程中也是参考这种思想,以古代女子三从四德举例,具体实现如下:

    1)责任链模式使用场景:

     1 /*****************************************************************************
     2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
     3 ------------------------------------------------------------------------------
     4 * File Module        :     ResponsibilityChainPatternUsage.c
     5 * Description        :     责任链模式的使用
     6 
     7 book@book-desktop:/work/projects/test/DesignPatterns/ResponsibilityChainPattern$ gcc -o ResponsibilityChainPatternUsage Woman.c Father.c Husband.c Son.c ResponsibilityChainPattern.c ResponsibilityChainPatternUsage.c 
     8 book@book-desktop:/work/projects/test/DesignPatterns/ResponsibilityChainPattern$ ./ResponsibilityChainPatternUsage
     9 女儿向父亲请示:
    10 女儿的请求是:我要出去逛街
    11 父亲的答复是:同意
    12 母亲向儿子请示:
    13 女儿的请求是:我要出去逛街
    14 儿子的答复是:同意
    15 
    16 * Created            :     2017.07.14.
    17 * Author            :     Yu Weifeng
    18 * Function List         :     
    19 * Last Modified     :     
    20 * History            :     
    21 ******************************************************************************/
    22 #include"stdio.h"
    23 #include"malloc.h"
    24 #include"stdlib.h"
    25 #include"string.h"
    26 #include"ResponsibilityChainPattern.h"
    27 
    28 
    29 
    30 
    31 /*****************************************************************************
    32 -Fuction        : main
    33 -Description    : 
    34 -Input            : 
    35 -Output         : 
    36 -Return         : 
    37 * Modify Date      Version         Author           Modification
    38 * -----------------------------------------------
    39 * 2017/07/14    V1.0.0         Yu Weifeng       Created
    40 ******************************************************************************/
    41 int main(int argc,char **argv)
    42 {
    43     T_Handle tFatherHandle=newFatherHandle;
    44     T_Handle tHusbandHandle=newHusbandHandle;
    45     T_Handle tSonHandle=newSonHandle;
    46 
    47     T_Woman tWoman=newWoman;
    48     tFatherHandle.SetNextHandle(&tHusbandHandle);
    49     tHusbandHandle.SetNextHandle(&tSonHandle);
    50 
    51     tFatherHandle.tFatherHandle.HandleMessage(&tWoman,&tFatherHandle);
    52 
    53     tWoman.SetType(SON_HANDLE_LEVEL);
    54     tFatherHandle.tFatherHandle.HandleMessage(&tWoman,&tFatherHandle);
    55     
    56     return 0;
    57 }
    ResponsibilityChainPatternUsage.c

    一般会有一个封装类对责任模式进行封装,也就是替代场景类,直接返回链中第一个处理者,具体链的设置不需要高层次模块关系,这样,更简化了高层次模块的调用,减少模块间的耦合。

    2)被调用者:

     1 /*****************************************************************************
     2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
     3 ------------------------------------------------------------------------------
     4 * File Module        :     ResponsibilityChainPattern.c
     5 * Description        :     责任链模式
     6                         以古代女子三从四德举例,女子先请求父亲,
     7                         父亲不处理则丈夫处理,丈夫不处理则儿子
     8                         处理,处理完可直接返回
     9 
    10 * Created            :     2017.07.14.
    11 * Author            :     Yu Weifeng
    12 * Function List         :     
    13 * Last Modified     :     
    14 * History            :     
    15 ******************************************************************************/
    16 #include"stdio.h"
    17 #include"malloc.h"
    18 #include"stdlib.h"
    19 #include"string.h"
    20 #include"ResponsibilityChainPattern.h"
    21 
    22 
    23 //static T_Handle g_tNextHandle[HANDLE_NUMBER]={NULL};//由于C类中的成员变量是静态的,所以放到子类中
    24 //static int g_iHandleNum=0;//如果放在父类,则需要定义为数组并定义长度与使用长度
    25 /*****************************************************************************
    26 -Fuction        : HandleMessage
    27 -Description    : 公有函数
    28 -Input            : 
    29 -Output         : 
    30 -Return         : 
    31 * Modify Date      Version         Author           Modification
    32 * -----------------------------------------------
    33 * 2017/07/14      V1.0.0         Yu Weifeng       Created
    34 ******************************************************************************/
    35 void HandleMessage(T_Woman *i_ptWoman,T_Handle *i_ptThis)
    36 {
    37     if(i_ptThis->GetLevel()==i_ptWoman->GetType())
    38     {
    39         i_ptThis->Handle(i_ptWoman);//调用子类的处理
    40     }
    41     else
    42     {
    43         if(i_ptThis->GetNextHandle()!=NULL)
    44         {
    45             i_ptThis->GetNextHandle()->tFatherHandle.HandleMessage(i_ptWoman,i_ptThis->GetNextHandle());
    46         }
    47         else
    48         {
    49             printf("没地方请示 了,按不同意处理
    ");
    50         }
    51     }
    52 }
    ResponsibilityChainPattern.c
     1 /*****************************************************************************
     2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
     3 ------------------------------------------------------------------------------
     4 * File Module        :     ResponsibilityChainPattern.h
     5 * Description        :     责任链模式
     6                                     
     7 * Created            :     2017.07.13.
     8 * Author            :     Yu Weifeng
     9 * Function List         :     
    10 * Last Modified     :     
    11 * History            :     
    12 ******************************************************************************/
    13 #ifndef RESPONSIBILITY_CHAIN_PATTERN_H
    14 #define RESPONSIBILITY_CHAIN_PATTERN_H
    15 
    16 
    17 #define FATHER_HANDLE_LEVEL        1
    18 #define HUSBAND_HANDLE_LEVEL    2
    19 #define SON_HANDLE_LEVEL            3
    20 
    21 #define HANDLE_NUMBER    3
    22 
    23 
    24 typedef struct Woman//女性类
    25 {
    26     int (*GetType)();
    27     char *  (*GetRequest)(); 
    28     void (*SetType)(int i_iType);//    void (*SetRequest)(char *i_strRequset);
    29 }T_Woman;
    30 
    31 struct Handle;
    32 
    33 typedef struct HandleManage//统一处理放到父类
    34 {
    35     void (*HandleMessage)(T_Woman *i_ptWoman,struct Handle *i_ptThis);//struct Handle *i_ptThis用于调用子类的方法
    36     //其他面向对象语言,调用子类的实现方法可直接调用
    37     //父类定义的子类需要实现的抽象方法即可
    38 
    39 }T_HandleManage;
    40 
    41 typedef struct Handle
    42 {//类似抽象类
    43     T_HandleManage tFatherHandle;//父类来实现(宏定义保证)
    44     void (*Handle)(T_Woman *i_ptWoman);//由子类实现,类似抽象方法//对请求处理
    45     int (*GetLevel)();
    46     void (*SetNextHandle)(struct Handle *i_ptHandle);//由于C类中的成员变量是静态的,所以放到子类中
    47     struct Handle *(*GetNextHandle)();
    48 }T_Handle;
    49 
    50 
    51 void HandleMessage(T_Woman *i_ptWoman,T_Handle *i_ptThis);
    52 
    53 void FatherReponse(T_Woman *i_ptWoman);
    54 int GetFatherHandleLevel();
    55 void SetFatherNextHandle(T_Handle*i_ptHandle);
    56 T_Handle *GetFatherNextHandle();
    57 //通过宏定义确保继承关系以及父类的不被覆写
    58 #define newFatherHandle {HandleMessage,FatherReponse,GetFatherHandleLevel,SetFatherNextHandle,GetFatherNextHandle}
    59 
    60 void HusbandReponse(T_Woman *i_ptWoman);
    61 int GetHusbandHandleLevel();
    62 void SetHusbandNextHandle(T_Handle*i_ptHandle);
    63 T_Handle *GetHusbandNextHandle();
    64 //通过宏定义确保继承关系以及父类的不被覆写
    65 #define newHusbandHandle {HandleMessage,HusbandReponse,GetHusbandHandleLevel,SetHusbandNextHandle,GetHusbandNextHandle}
    66 
    67 void SonReponse(T_Woman *i_ptWoman);
    68 int GetSonHandleLevel();
    69 void SetSonNextHandle(T_Handle*i_ptHandle);
    70 T_Handle *GetSonNextHandle();
    71 //通过宏定义确保继承关系以及父类的不被覆写
    72 #define newSonHandle {HandleMessage,SonReponse,GetSonHandleLevel,SetSonNextHandle,GetSonNextHandle}
    73 
    74 
    75 
    76 
    77 
    78 
    79 
    80 
    81 
    82 int GetType();
    83 char *GetRequest();
    84 void SetType(int i_iType);
    85 #define newWoman {GetType,GetRequest,SetType}
    86 
    87 #endif
    ResponsibilityChainPattern.h
     1 /*****************************************************************************
     2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
     3 ------------------------------------------------------------------------------
     4 * File Module        :     Father.c
     5 * Description        :     责任链模式中的角色
     6                         处理者(女性的父亲)
     7 * Created            :     2017.07.14.
     8 * Author            :     Yu Weifeng
     9 * Function List         :     
    10 * Last Modified     :     
    11 * History            :     
    12 ******************************************************************************/
    13 #include"stdio.h"
    14 #include"malloc.h"
    15 #include"stdlib.h"
    16 #include"string.h"
    17 #include"ResponsibilityChainPattern.h"
    18 
    19 static T_Handle g_tFatherNextHandle={NULL};
    20 
    21 /*****************************************************************************
    22 -Fuction        : FatherHandle
    23 -Description    : 对女儿请求的回应处理
    24 -Input            : 
    25 -Output         : 
    26 -Return         : 
    27 * Modify Date      Version         Author           Modification
    28 * -----------------------------------------------
    29 * 2017/07/14      V1.0.0         Yu Weifeng       Created
    30 ******************************************************************************/
    31 void FatherReponse(T_Woman *i_ptWoman)
    32 {
    33     printf("女儿向父亲请示:
    ");
    34     printf("%s
    ",i_ptWoman->GetRequest());
    35     printf("父亲的答复是:同意
    ");
    36 }
    37 
    38 /*****************************************************************************
    39 -Fuction        : GetFatherHandleLevel
    40 -Description    : 
    41 -Input            : 
    42 -Output         : 
    43 -Return         : 
    44 * Modify Date      Version         Author           Modification
    45 * -----------------------------------------------
    46 * 2017/07/14      V1.0.0         Yu Weifeng       Created
    47 ******************************************************************************/
    48 int GetFatherHandleLevel()
    49 {
    50     return FATHER_HANDLE_LEVEL;
    51 }
    52 
    53 /*****************************************************************************
    54 -Fuction        : GetFatherNextHandle
    55 -Description    : 
    56 -Input            : 
    57 -Output         : 
    58 -Return         : 
    59 * Modify Date      Version         Author           Modification
    60 * -----------------------------------------------
    61 * 2017/07/14      V1.0.0         Yu Weifeng       Created
    62 ******************************************************************************/
    63 T_Handle *GetFatherNextHandle()
    64 {
    65     return &g_tFatherNextHandle;
    66 }
    67 
    68 /*****************************************************************************
    69 -Fuction        : SetFatherNextHandle
    70 -Description    : 
    71 -Input            : 
    72 -Output         : 
    73 -Return         : 
    74 * Modify Date      Version         Author           Modification
    75 * -----------------------------------------------
    76 * 2017/07/14      V1.0.0         Yu Weifeng       Created
    77 ******************************************************************************/
    78 void SetFatherNextHandle(T_Handle*i_ptHandle)
    79 {
    80     memcpy(&g_tFatherNextHandle,i_ptHandle,sizeof(T_Handle));
    81 }
    Father.c
     1 /*****************************************************************************
     2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
     3 ------------------------------------------------------------------------------
     4 * File Module        :     Husband.c
     5 * Description        :     责任链模式中的角色
     6                         处理者(女性的丈夫)
     7 * Created            :     2017.07.14.
     8 * Author            :     Yu Weifeng
     9 * Function List         :     
    10 * Last Modified     :     
    11 * History            :     
    12 ******************************************************************************/
    13 #include"stdio.h"
    14 #include"malloc.h"
    15 #include"stdlib.h"
    16 #include"string.h"
    17 #include"ResponsibilityChainPattern.h"
    18 
    19 
    20 
    21 
    22 static T_Handle g_tHusbandNextHandle={NULL};
    23 
    24 /*****************************************************************************
    25 -Fuction        : HusbandHandle
    26 -Description    : 对妻子请求的回应处理
    27 -Input            : 
    28 -Output         : 
    29 -Return         : 
    30 * Modify Date      Version         Author           Modification
    31 * -----------------------------------------------
    32 * 2017/07/14      V1.0.0         Yu Weifeng       Created
    33 ******************************************************************************/
    34 void HusbandReponse(T_Woman *i_ptWoman)
    35 {
    36     printf("妻子向丈夫请示:
    ");
    37     printf("%s
    ",i_ptWoman->GetRequest());
    38     printf("丈夫的答复是:同意
    ");
    39 }
    40 
    41 /*****************************************************************************
    42 -Fuction        : GetHusbandHandleLevel
    43 -Description    : 
    44 -Input            : 
    45 -Output         : 
    46 -Return         : 
    47 * Modify Date      Version         Author           Modification
    48 * -----------------------------------------------
    49 * 2017/07/14      V1.0.0         Yu Weifeng       Created
    50 ******************************************************************************/
    51 int GetHusbandHandleLevel()
    52 {
    53     return HUSBAND_HANDLE_LEVEL;
    54 }
    55 
    56 /*****************************************************************************
    57 -Fuction        : GetHusbandNextHandle
    58 -Description    : 
    59 -Input            : 
    60 -Output         : 
    61 -Return         : 
    62 * Modify Date      Version         Author           Modification
    63 * -----------------------------------------------
    64 * 2017/07/14      V1.0.0         Yu Weifeng       Created
    65 ******************************************************************************/
    66 T_Handle *GetHusbandNextHandle()
    67 {
    68     return &g_tHusbandNextHandle;
    69 }
    70 
    71 /*****************************************************************************
    72 -Fuction        : SetHusbandNextHandle
    73 -Description    : 
    74 -Input            : 
    75 -Output         : 
    76 -Return         : 
    77 * Modify Date      Version         Author           Modification
    78 * -----------------------------------------------
    79 * 2017/07/14      V1.0.0         Yu Weifeng       Created
    80 ******************************************************************************/
    81 void SetHusbandNextHandle(T_Handle*i_ptHandle)
    82 {
    83     memcpy(&g_tHusbandNextHandle,i_ptHandle,sizeof(T_Handle));
    84 }
    Husband.c
     1 /*****************************************************************************
     2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
     3 ------------------------------------------------------------------------------
     4 * File Module        :     Son.c
     5 * Description        :     责任链模式中的角色
     6                         处理者(女性的儿子)
     7 * Created            :     2017.07.14.
     8 * Author            :     Yu Weifeng
     9 * Function List         :     
    10 * Last Modified     :     
    11 * History            :     
    12 ******************************************************************************/
    13 #include"stdio.h"
    14 #include"malloc.h"
    15 #include"stdlib.h"
    16 #include"string.h"
    17 #include"ResponsibilityChainPattern.h"
    18 
    19 
    20 static T_Handle g_tSonNextHandle={NULL};
    21 
    22 /*****************************************************************************
    23 -Fuction        : SonHandle
    24 -Description    : 对母亲请求的回应处理
    25 -Input            : 
    26 -Output         : 
    27 -Return         : 
    28 * Modify Date      Version         Author           Modification
    29 * -----------------------------------------------
    30 * 2017/07/14      V1.0.0         Yu Weifeng       Created
    31 ******************************************************************************/
    32 void SonReponse(T_Woman *i_ptWoman)
    33 {
    34     printf("母亲向儿子请示:
    ");
    35     printf("%s
    ",i_ptWoman->GetRequest());
    36     printf("儿子的答复是:同意
    ");
    37 }
    38 
    39 /*****************************************************************************
    40 -Fuction        : GetSonHandleLevel
    41 -Description    : 
    42 -Input            : 
    43 -Output         : 
    44 -Return         : 
    45 * Modify Date      Version         Author           Modification
    46 * -----------------------------------------------
    47 * 2017/07/14      V1.0.0         Yu Weifeng       Created
    48 ******************************************************************************/
    49 int GetSonHandleLevel()
    50 {
    51     return SON_HANDLE_LEVEL;
    52 }
    53 
    54 /*****************************************************************************
    55 -Fuction        : GetSonNextHandle
    56 -Description    : 
    57 -Input            : 
    58 -Output         : 
    59 -Return         : 
    60 * Modify Date      Version         Author           Modification
    61 * -----------------------------------------------
    62 * 2017/07/14      V1.0.0         Yu Weifeng       Created
    63 ******************************************************************************/
    64 T_Handle *GetSonNextHandle()
    65 {
    66     return &g_tSonNextHandle;
    67 }
    68 
    69 /*****************************************************************************
    70 -Fuction        : SetSonNextHandle
    71 -Description    : 
    72 -Input            : 
    73 -Output         : 
    74 -Return         : 
    75 * Modify Date      Version         Author           Modification
    76 * -----------------------------------------------
    77 * 2017/07/14      V1.0.0         Yu Weifeng       Created
    78 ******************************************************************************/
    79 void SetSonNextHandle(T_Handle*i_ptHandle)
    80 {
    81     memcpy(&g_tSonNextHandle,i_ptHandle,sizeof(T_Handle));
    82 }
    Son.c
     1 /*****************************************************************************
     2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
     3 ------------------------------------------------------------------------------
     4 * File Module        :     Woman.c
     5 * Description        :     责任链模式中的角色
     6                         请求者(女性)
     7 * Created            :     2017.07.14.
     8 * Author            :     Yu Weifeng
     9 * Function List         :     
    10 * Last Modified     :     
    11 * History            :     
    12 ******************************************************************************/
    13 #include"stdio.h"
    14 #include"malloc.h"
    15 #include"stdlib.h"
    16 #include"string.h"
    17 #include"ResponsibilityChainPattern.h"
    18 
    19 
    20 
    21 static int g_iType=FATHER_HANDLE_LEVEL;
    22 static char *g_strRequest="女儿的请求是:我要出去逛街";
    23 /*****************************************************************************
    24 -Fuction        : GetRequest
    25 -Description    : 公有函数
    26 -Input            : 
    27 -Output         : 
    28 -Return         : 
    29 * Modify Date      Version         Author           Modification
    30 * -----------------------------------------------
    31 * 2017/07/14       V1.0.0         Yu Weifeng       Created
    32 ******************************************************************************/
    33 char *GetRequest()
    34 {
    35     return g_strRequest;
    36 }
    37 /*****************************************************************************
    38 -Fuction        : GetType
    39 -Description    : 公有函数
    40 -Input            : 
    41 -Output         : 
    42 -Return         : 
    43 * Modify Date      Version         Author           Modification
    44 * -----------------------------------------------
    45 * 2017/07/14       V1.0.0         Yu Weifeng       Created
    46 ******************************************************************************/
    47 int GetType()
    48 {
    49     return g_iType;
    50 }
    51 /*****************************************************************************
    52 -Fuction        : SetType
    53 -Description    : 公有函数
    54 -Input            : 
    55 -Output         : 
    56 -Return         : 
    57 * Modify Date      Version         Author           Modification
    58 * -----------------------------------------------
    59 * 2017/07/14       V1.0.0         Yu Weifeng       Created
    60 ******************************************************************************/
    61 void SetType(int i_iType)
    62 {
    63     g_iType=i_iType;
    64 }
    Woman.c

    3)执行结果:

    book@book-desktop:/work/projects/test/DesignPatterns/ResponsibilityChainPattern$ gcc -o

    ResponsibilityChainPatternUsage Woman.c Father.c Husband.c Son.c ResponsibilityChainPattern.c

    ResponsibilityChainPatternUsage.c

    book@book-desktop:/work/projects/test/DesignPatterns/ResponsibilityChainPattern$

    ./ResponsibilityChainPatternUsage

    女儿向父亲请示:

    女儿的请求是:我要出去逛街

    父亲的答复是:同意

    母亲向儿子请示:

    女儿的请求是:我要出去逛街

    儿子的答复是:同意

    4)详细代码:

    https://github.com/fengweiyu/DesignThinking/tree/master/DesignPatterns/BehavioralDesignPatterns/ResponsibilityChainPattern

    三、使用场景

    1.请求可以由多个处理者处理,同时要将请求和处理分开时

    四、优点

    非常显著的优点是将请求和处理分开。请求者可以不用知道是谁处理的(责任链模式核心),处理者可以不用知道请求的全貌。

    避免了请求的发送者和接收者之间的耦合关系。

    五、缺点

    1.性能问题

    每个请求都是从链头遍历到链尾,特别是在链比较长的时候,性能是一个非常大的问题。

    2.调试不太方便

    特别是链比较长,环节比较多的时候,由于采用了类似递归的方式,调试的时候逻辑可能比较复杂

    因此需注意:

    1.链中节点数量需要控制,避免出现超长链的情况

    一般做法是在处理中设置一个最大结点数量,在设置下一个结点中判断是否已经超长,超过则不允许建立。

    2.责任链模式和观察者模式的区别

    责任链模式和观察者模式最大的区别是,责任链处理完后可以直接返回到最初的结点即根节点。而观察者模式是相邻两个结点结构,即处理完返回时也是返回到上一个结点。

  • 相关阅读:
    YTU 2972: C语言习题5.24--文件操作1
    YTU 2925: 文件操作--文本文件读入
    YTU 2924: 文件操作--二进制文件读入
    PHP中$_SERVER[HTTP_REFERER]
    form控件中添加js代码,用javascript:某代码段(注意javascript之后用双引号)
    js中的location.href与location
    问题:下载页面代码? 以及php中header的用法。
    随笔
    __FILE__ $_SERVER['PHP_SELF'] $_SERVER['SCRIPT_NAME'] $_SERVER['SCRIPT_FILENAME'] 的区别
    #deebef 背景色
  • 原文地址:https://www.cnblogs.com/yuweifeng/p/7197198.html
Copyright © 2020-2023  润新知