20.设计模式-职责链模式

职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

需求

流程申请审批,如加薪、请假

代码

业务类

c 复制代码
#include <stdio.h>
#include <string.h>
#include "uthash-master-src/src/uthash.h"

typedef enum {
    MANAGEER,
    DIRECTOR,
    GENERALMANGER,
    LEVELMAX
} Level;

typedef enum {
    ADDMONEY,
    REST,
    REQUESTMAX
} RequstType;

char *RequestContent[] = {
    "加薪",
    "请假"
};

typedef struct Request {
    RequstType type;
    int num;
} Request;

typedef struct Manager {
    Level level;
    char *name;
    // 假设只有一个直接上级
    struct Manager *superiors;
    void (*request)(struct Manager *, Request *);
} Manager;
// 经理
typedef struct CommonManger {
    Manager base;
} CommonManger;

void CommonMangerRequest(Manager *obj, Request *req) {
    if(req->type == REST && req->num <= 2) {
        printf("%s:%s 数量%d 被批准\n", obj->name, RequestContent[req->type], req->num);
    }
    else {
        obj->superiors->request(obj->superiors, req);
    }
}

Manager *InitCommonManager(char *name) {
    CommonManger *obj = (CommonManger *)malloc(sizeof(CommonManger));
    obj->base.level = MANAGEER;
    obj->base.name = name;
    // obj->base.superiors = superior;
    obj->base.request = CommonMangerRequest;
    return (Manager *)obj;
}
// 总监
typedef struct Director {
    Manager base;
} Director;

void DirectorRequest(Manager *obj, Request *req) {
    if(req->type == REST && req->num <= 5) {
        printf("%s:%s 数量%d 被批准\n", obj->name, RequestContent[req->type], req->num);
    }
    else {
        obj->superiors->request(obj->superiors, req);
    }
}

Manager *InitDirector(char *name) {
    Director *obj = (Director *)malloc(sizeof(Director));
    obj->base.level = DIRECTOR;
    obj->base.name = name;
    // obj->base.superiors = superior;
    obj->base.request = DirectorRequest;
    return (Manager *)obj;
}
// 总经理
typedef struct GeneralManager {
    Manager base;
} GeneralManager;

void GeneralManagerRequest(Manager *obj, Request *req) {
    if(req->type == REST) {
        printf("%s:%s 数量%d 被批准\n", obj->name, RequestContent[req->type], req->num);
    }
    else {
        if(req->num <= 500) {
            printf("%s:%s 数量%d 被批准\n", obj->name, RequestContent[req->type], req->num);
        }
        else {
            printf("%s:%s 数量%d 再说吧\n", obj->name, RequestContent[req->type], req->num);
        }
    }
}

Manager *InitGeneralManager(char *name) {
    GeneralManager *obj = (GeneralManager *)malloc(sizeof(GeneralManager));
    obj->base.level = GENERALMANGER;
    obj->base.name = name;
    // obj->base.superiors = superior;
    obj->base.request = GeneralManagerRequest;
    return (Manager *)obj;
}

typedef struct {
    char *name;
    Level level;
} WorkInfo;

typedef struct ChainOfResponsbility {
    WorkInfo pre;
    WorkInfo next;
} ChainOfResponsbility;

ChainOfResponsbility cofry[] = {
    {{"jingli",MANAGEER}, {"zongjian",DIRECTOR}},
    {{"zongjian",DIRECTOR}, {"zongjingli", GENERALMANGER}}
};

typedef Manager *(*CreateManagerInterface)(char *);

CreateManagerInterface cmi[] = {
    InitCommonManager,
    InitDirector,
    InitGeneralManager
};

typedef struct HashMap {
    char *name;
    Manager *manager;
    UT_hash_handle hh;
} HashMap;

客户端

c 复制代码
int main() {
    int n = sizeof(cofry)/sizeof(ChainOfResponsbility);
    HashMap *hashtable = NULL;
    HashMap *found;
    for(int i=0; i<n; i++) {
        Manager *pre, *next;
        HASH_FIND_STR(hashtable, cofry[i].pre.name, found);
        if(found == NULL) {
            found = (HashMap *)malloc(sizeof(HashMap));
            found->name = cofry[i].pre.name;
            HASH_ADD_STR(hashtable, name, found);
            found->manager = cmi[cofry[i].pre.level](cofry[i].pre.name);
        }
        pre = found->manager;
        HASH_FIND_STR(hashtable, cofry[i].next.name, found);
        if(found == NULL) {
            found = (HashMap *)malloc(sizeof(HashMap));
            found->name = cofry[i].next.name;
            HASH_ADD_STR(hashtable, name, found);
            pre->superiors = cmi[cofry[i].next.level](cofry[i].next.name);
            found->manager = pre->superiors;
        }
        else {
            pre->superiors = found->manager;
        }
    }
    printf("initial complete\n");
    HASH_FIND_STR(hashtable, cofry[0].pre.name, found);
    Manager *entry = found->manager;
    Request req[] = {
        {REST, 1},
        {REST, 3},
        {ADDMONEY, 500},
        {ADDMONEY, 1000}
    };
    n = sizeof(req)/sizeof(Request);
    for(int i=0; i<n; i++) {
        entry->request(entry, &(req[i]));
    }
    return 0;
}

客户端打印:

text 复制代码
jingli:请假 数量1 被批准
zongjian:请假 数量3 被批准
zongjingli:加薪 数量500 被批准
zongjingli:加薪 数量1000 再说吧

UML图

总结

  • 职责链模式的优点?
    职责模式的处理过程是当客户提交一个请求时,请求是沿链传递直至有一个ConcreteHandler对象负责处理它。这就使得接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构。结果是职责链可简化对象的相互连接,它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接受者的引用。
相关推荐
J_liaty3 小时前
23种设计模式一代理模式
设计模式·代理模式
苏渡苇9 小时前
优雅应对异常,从“try-catch堆砌”到“设计驱动”
java·后端·设计模式·学习方法·责任链模式
短剑重铸之日10 小时前
《设计模式》第十一篇:总结
java·后端·设计模式·总结
feasibility.11 小时前
AI 编程助手进阶指南:从 Claude Code 到 OpenCode 的工程化经验总结
人工智能·经验分享·设计模式·自动化·agi·skills·opencode
BD_Marathon11 小时前
七大设计原则介绍
设计模式
YigAin13 小时前
Unity23种设计模式之 享元模式
设计模式·享元模式
范纹杉想快点毕业1 天前
实战级ZYNQ中断状态机FIFO设计
java·开发语言·驱动开发·设计模式·架构·mfc
茂桑1 天前
DDD领域驱动设计-基础设施层
设计模式·架构
小温冲冲1 天前
通俗且全面精讲工厂设计模式
设计模式
进击的小头1 天前
设计模式与C语言高级特性的结合
c语言·设计模式