职责链模式(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对象负责处理它。这就使得接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构。结果是职责链可简化对象的相互连接,它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接受者的引用。