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对象负责处理它。这就使得接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构。结果是职责链可简化对象的相互连接,它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接受者的引用。
相关推荐
她和夏天一样热17 小时前
【设计模式】工厂方法模式在开发中的真实应用
设计模式·工厂方法模式
烤麻辣烫1 天前
23种设计模式(新手)-9单例模式
java·开发语言·学习·设计模式·intellij-idea
资生算法程序员_畅想家_剑魔1 天前
Java常见技术分享-设计模式的六大原则
java·开发语言·设计模式
刀法如飞1 天前
从零手搓一个类Spring框架,彻底搞懂Spring核心原理
java·设计模式·架构设计
一条闲鱼_mytube1 天前
智能体设计模式全景总结:21个模式快速串联指南
网络·设计模式
老蒋每日coding1 天前
AI Agent 设计模式系列(十五)—— A2A Agent 间通信模式
人工智能·设计模式
Leo July1 天前
【Java】Java设计模式实战指南:从原理到框架应用
java·开发语言·设计模式
老蒋每日coding1 天前
AI Agent 设计模式系列(十四)—— 知识检索(RAG)模式
人工智能·设计模式·langchain
Yu_Lijing2 天前
基于C++的《Head First设计模式》笔记——模式合作
c++·笔记·设计模式