职责链模式(C语言实现)
发布时间:2020-12-13 20:20:59 所属栏目:PHP教程 来源:网络整理
导读:一. 概述 职责链模式: 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。 二. 举个例子 员工要求加薪 公司的管理者一共有三级:总经理、总监、经理,如
一. 概述 职责链模式: 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。 二. 举个例子 员工要求加薪
公司的管理者一共有三级:总经理、总监、经理,如果一个员工要求加薪,应该向主管的经理申请,如果加薪的数量在经理的职权内,那么经理可以直接批准,否则将申请上交给总监。总监的处理方式也一样,总经理可以处理所有请求。这就是典型的职责链模式,请求的处理形成了一条链,直到有一个对象处理请求。 结构图如下:
假设:
经理可以处理薪水的范围在:0~500 则代码如下:
abstractClass.h
#ifndef ABSTRACTCLASS_H
#define ABSTRACTCLASS_H
#include <stdlib.h>
#include <stdarg.h>
typedef struct {
size_t size;
void* (*ctor)(void *_self,va_list *params);
void* (*dtor)(void *_self);
} AbstractClass;
#endif
handle.h
#ifndef HANDLE_H
#define HANDLE_H
#include <stdlib.h>
#include <stdarg.h>
typedef struct {
size_t size;
void* (*ctor)(void *_self,va_list *params);
void* (*dtor)(void *_self);
void (*setSuccessor)(void *_self,void *succ);
void *(*getSuccessor)(const void *_self);
void (*handleRequest)(const void *_self,int request);
} Handle;
#endif
concreteHandleA.h
#ifndef CONCRETEHANDLEA_H
#define CONCRETEHANDLEA_H
typedef struct {
const void *_;
void *succ;
} _ConcreteHandleA;
extern const void *ConcreteHandleA;
#endif
concreteHandleA.c
#include "handle.h"
#include "concreteHandleA.h"
#include <stdlib.h>
#include <stdio.h>
static void *concreteHandleACtor(void *_self,va_list *params) {
_ConcreteHandleA *self = _self;
return self;
}
static void *concreteHandleADtor(void *_self) {
_ConcreteHandleA *self = _self;
self->succ = NULL;
return self;
}
static void concreteHandleASetSuccessor(void *_self,void *_succ) {
_ConcreteHandleA *self = _self;
self->succ = _succ;
}
static void *concreteHandleAGetSuccessor(const void *_self) {
const _ConcreteHandleA *self = _self;
return self->succ;
}
static void concreteHandleAhandleRequest(const void *_self,int request) {
if (request >= 0 && request < 500) {
fprintf(stdout,"ConcreteHandleA deal with: %d
",request);
} else if (concreteHandleAGetSuccessor(_self) != NULL) {
const Handle * const *succ = concreteHandleAGetSuccessor(_self);
(*succ)->handleRequest(succ,request);
} else {
fprintf(stderr,"Can't deal with: %d
",request);
}
}
static const Handle _concreteHandleA = {
sizeof(_ConcreteHandleA),concreteHandleACtor,concreteHandleADtor,concreteHandleASetSuccessor,concreteHandleAGetSuccessor,concreteHandleAhandleRequest
};
const void *ConcreteHandleA = &_concreteHandleA; concreteHandleB.h
#ifndef CONCRETEHANDLEB_H
#define CONCRETEHANDLEB_H
typedef struct {
const void *_;
void *succ;
} _ConcreteHandleB;
extern const void *ConcreteHandleB;
#endif
concreteHandleB.c #include "handle.h"
#include "concreteHandleB.h"
#include <stdlib.h>
#include <stdio.h>
static void *concreteHandleBCtor(void *_self,va_list *params) {
_ConcreteHandleB *self = _self;
return self;
}
static void *concreteHandleBDtor(void *_self) {
_ConcreteHandleB *self = _self;
self->succ = NULL;
return self;
}
static void concreteHandleBSetSuccessor(void *_self,void *_succ) {
_ConcreteHandleB *self = _self;
self->succ = _succ;
}
static void *concreteHandleBGetSuccessor(const void *_self) {
const _ConcreteHandleB *self = _self;
return self->succ;
}
static void concreteHandleBhandleRequest(const void *_self,int request) {
if (request >= 500 && request < 1000) {
fprintf(stdout,"ConcreteHandleB deal with: %d
",request);
} else if (concreteHandleBGetSuccessor(_self) != NULL) {
const Handle * const *succ = concreteHandleBGetSuccessor(_self);
(*succ)->handleRequest(succ,request);
}
}
static const Handle _concreteHandleB = {
sizeof(_ConcreteHandleB),concreteHandleBCtor,concreteHandleBDtor,concreteHandleBSetSuccessor,concreteHandleBGetSuccessor,concreteHandleBhandleRequest
};
const void *ConcreteHandleB = &_concreteHandleB;
concreteHandleC.h #ifndef CONCRETEHANDLEC_H
#define CONCRETEHANDLEC_H
typedef struct {
const void *_;
void *succ;
} _ConcreteHandleC;
extern const void *ConcreteHandleC;
#endif
concreteHandleC.c #include "handle.h"
#include "concreteHandleC.h"
#include <stdlib.h>
#include <stdio.h>
static void *concreteHandleCCtor(void *_self,va_list *params) {
_ConcreteHandleC *self = _self;
return self;
}
static void *concreteHandleCDtor(void *_self) {
_ConcreteHandleC *self = _self;
self->succ = NULL;
return self;
}
static void concreteHandleCSetSuccessor(void *_self,void *_succ) {
_ConcreteHandleC *self = _self;
self->succ = _succ;
}
static void *concreteHandleCGetSuccessor(const void *_self) {
const _ConcreteHandleC *self = _self;
return self->succ;
}
static void concreteHandleChandleRequest(const void *_self,int request) {
if (request >= 1000 && request < 2000) {
fprintf(stdout,"ConcreteHandleC deal with: %d
",request);
} else if (concreteHandleCGetSuccessor(_self) != NULL) {
const Handle * const *succ = concreteHandleCGetSuccessor(_self);
(*succ)->handleRequest(succ,request);
}
}
static const Handle _concreteHandleC = {
sizeof(_ConcreteHandleC),concreteHandleCCtor,concreteHandleCDtor,concreteHandleCSetSuccessor,concreteHandleCGetSuccessor,concreteHandleChandleRequest
};
const void *ConcreteHandleC = &_concreteHandleC;
new.h #ifndef NEW_H
#define NEW_H
void *New(const void *_class,...);
void Delete(void *_class);
void SetSuccessor(void *_handle,void *_succ);
void HandleRequest(void *_handle,int request);
#endif
new.c #include "new.h"
#include "abstractClass.h"
#include "handle.h"
#include <stdarg.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
void *New(const void *_class,...) {
const AbstractClass *class = _class;
void *p = calloc(1,class->size);
assert(p);
*(const AbstractClass **)p = class;
if (class->ctor) {
va_list params;
va_start(params,_class);
p = class->ctor(p,¶ms);
va_end(params);
}
return p;
}
void Delete(void *_class) {
const AbstractClass **class = _class;
if (_class && *class && (*class)->dtor) {
_class = (*class)->dtor(_class);
}
free(_class);
}
void SetSuccessor(void *_handle,void *_succ) {
Handle **handle = _handle;
if (_handle && *handle && (*handle)->setSuccessor) {
(*handle)->setSuccessor(_handle,_succ);
}
}
void HandleRequest(void *_handle,int request) {
Handle **handle = _handle;
if (_handle && *handle && (*handle)->handleRequest) {
(*handle)->handleRequest(_handle,request);
}
}
main.c #include "new.h"
#include "concreteHandleA.h"
#include "concreteHandleB.h"
#include "concreteHandleC.h"
int main(int argc,char *argv[]) {
void *h1 = New(ConcreteHandleA);
void *h2 = New(ConcreteHandleB);
void *h3 = New(ConcreteHandleC);
SetSuccessor(h1,h2);
SetSuccessor(h2,h3);
HandleRequest(h1,300);
HandleRequest(h1,600);
HandleRequest(h1,1500);
HandleRequest(h1,3000);
Delete(h1);
Delete(h2);
Delete(h3);
return 0;
}
图片来源:http://blog.csdn.net/hmsiwtv/article/details/9627307 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |