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对象负责处理它。这就使得接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构。结果是职责链可简化对象的相互连接,它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接受者的引用。
相关推荐
Momentary_SixthSense20 小时前
设计模式之工厂模式
java·开发语言·设计模式
Java码农也是农20 小时前
Multi-Agent 系统设计模式
设计模式·agent·multi-agent
sg_knight20 小时前
设计模式实战:状态模式(State)
python·ui·设计模式·状态模式·state
workflower1 天前
深度学习是通用型人工智能的基础
人工智能·深度学习·设计模式·软件工程·软件构建·制造
Meme Buoy1 天前
11.3设计模式-新
设计模式
cmpxr_1 天前
【单片机】常用设计模式
单片机·嵌入式硬件·设计模式
无籽西瓜a1 天前
【西瓜带你学设计模式 | 第十五期 - 策略模式】策略模式 —— 算法封装与动态替换实现、优缺点与适用场景
java·后端·设计模式·软件工程·策略模式
Kel2 天前
Claude Code 架构深度剖析:从终端输入到大模型响应的完整过程
人工智能·设计模式·架构
￰meteor2 天前
23种设计模式 -【观察者】
设计模式
妙蛙种子3112 天前
【Java设计模式 | 创建者模式】 抽象工厂模式
java·开发语言·后端·设计模式·抽象工厂模式