职责链模式(C语言实现)

一. 概述

职责链模式:

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

二. 举个例子

员工要求加薪

公司的管理者一共有三级:总经理、总监、经理,如果一个员工要求加薪,应该向主管的经理申请,如果加薪的数量在经理的职权内,那么经理可以直接批准,否则将申请上交给总监。总监的处理方式也一样,总经理可以处理所有请求。这就是典型的职责链模式,请求的处理形成了一条链,直到有一个对象处理请求。

结构图如下:

假设:

经理可以处理薪水的范围在:0~500
总监可以处理薪水的范围在:500~1000
总经理可以处理薪水的范围在:1000~2000

则代码如下:


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);
} else {
fprintf(stderr, "Can't deal with: %d
", 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);
} else {
fprintf(stderr, "Can't deal with: %d
", 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

波比源码 – 精品源码模版分享 | www.bobi11.com
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!

波比源码 » 职责链模式(C语言实现)

发表评论

Hi, 如果你对这款模板有疑问,可以跟我联系哦!

联系站长
赞助VIP 享更多特权,建议使用 QQ 登录
喜欢我嘛?喜欢就按“ctrl+D”收藏我吧!♡