zoukankan      html  css  js  c++  java
  • 设计模式之责任链模式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.责任链模式和观察者模式的区别

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

  • 相关阅读:
    Linux 共享库
    使用Visual Studio(VS)开发Qt程序代码提示功能的实现(转)
    ZOJ 3469 Food Delivery(区间DP)
    POJ 2955 Brackets (区间DP)
    HDU 3555 Bomb(数位DP)
    HDU 2089 不要62(数位DP)
    UESTC 1307 windy数(数位DP)
    HDU 4352 XHXJ's LIS(数位DP)
    POJ 3252 Round Numbers(数位DP)
    HDU 2476 String painter (区间DP)
  • 原文地址:https://www.cnblogs.com/yuweifeng/p/7197198.html
Copyright © 2011-2022 走看看