一个用C实现的Dispatch框架

标签: dispatch 框架 | 发表时间:2010-09-08 22:30 | 作者:dreamhead kevH
出处:http://dreamhead.blogbus.com

用条件语句做分发是一件很常见的事:
switch(msg->id) {
    case ID1:
        ID1Handler(msg);
        break;
    case ID2:
        ID2Handler(msg);
        break;
    ...
}

条件稍微多一些点,函数就会变得冗长不堪。有的团队会直接用if..else,进行判断,于是我们有幸知道了,VC不支持超过128个的选择分支。为了让这种代码的可维护性更好,我们做了一些尝试。

下面定义了一个dispatcher:
BEGIN_DISPATCHER(MSG, ID, MsgHandler)
    DISPATCH_ITEM(ID1, ID1Handler)
    DISPATCH_ITEM(ID2, ID2Handler)
END_DISPATCHER(PCU_DisasterHandler)

首先,用BEGIN_DISPATCH_MAP定义了这个dispatcher的名字(MSG),用做分发键值的类型(ID)和处理函数的类型(MsgHandler)。接下来,用DISPATCH_ITEM定义了几个分发项,也就是说,如果传入的值是ID1,会用ID1Handler进行处理,如果是ID2,则对应着ID2Handler。最后,用END_DISPATCH_MAP定义了一个错误处理函数。这样的话,就把使用的时候,就不必额外去做判空的操作了。这是Null Object模式的一种体现。

这个dispatcher的使用方式如下:
dispatch(to(MSG), with(msg->id))(msg);

这段代码的含义是使用MSG这个dispatcher,根据msg->id找到对应的处理函数,传入的参数是msg。

这个dispatch框架的实现如下:
#include <string.h>
#define SIZE_OF_ARRAY(array) sizeof(array)/sizeof(array[0])

/* dispatcher definition */

#define __DISPATCHER_NAME(name) __dispatcher_##name
#define __DISPATCH_ITEM_NAME(name) __dispatch_item_##name
#define __IsMatched(target, source) (0 == memcmp(&target, &source, sizeof(target)))

#define BEGIN_DISPATCHER(name, key_type, handler_type) \
    struct __DISPATCH_ITEM_NAME(name) {\
        key_type key;\
        handler_type *handler;\
    };\
    \
handler_type* __DISPATCHER_NAME(name)(key_type key) \
{\
    static struct __DISPATCH_ITEM_NAME(name) dispatchers[] = {\

#define END_DISPATCHER(disaster_handler) \
    };\
    int i;\
    int array_size = SIZE_OF_ARRAY(dispatchers); \
    for (i = 0; i < array_size; i++)\
    {\
        if (__IsMatched(dispatchers[i].key, key)) {\
            return dispatchers[i].handler;\
        }\
    }\
    return disaster_handler;\
}

#define DISPATCH_ITEM(key, handler) {key, handler},
#define DISPATCH_ITEM_2(key1, key2, handler) {key1, key2, handler},
#define DISPATCH_ITEM_3(key1, key2, key3, handler) {key1, key2, key3, handler},
#define dispatch(name, key) __DISPATCHER_NAME(name)(key)
#define to(name) name
#define with(key) key

从这里可以看出,定义dispatcher,实际上是定义了一个函数,这个函数的返回值是一个函数指针,而这个函数指针的类型是由handler_type定义的。这样的话,就解决了不同dispatcher之间函数参数不同的问题。

当然,这个处理里面采用了最简单的数组,在分发项不是很多的情况下是适用的。如果分发项较多,可以考虑改为map实现。另外,这里还运用了一些宏的技巧。在写应用代码时,我们并不鼓励多用宏。但写一些框架代码,为了提高使用上的表现力时,宏也会是一个利器。

如果有兴趣,欢迎讨论!

相关 [dispatch 框架] 推荐:

一个用C实现的Dispatch框架

- kevH - 梦想风暴
用条件语句做分发是一件很常见的事:. 条件稍微多一些点,函数就会变得冗长不堪. 有的团队会直接用if..else,进行判断,于是我们有幸知道了,VC不支持超过128个的选择分支. 为了让这种代码的可维护性更好,我们做了一些尝试. 下面定义了一个dispatcher:. 首先,用BEGIN_DISPATCH_MAP定义了这个dispatcher的名字(MSG),用做分发键值的类型(ID)和处理函数的类型(MsgHandler).

PHP框架 Yaf

- Le - 开源中国社区最新软件
Yaf是一个C语言编写的PHP框架,Yaf 的特点: 用C语言开发的PHP框架, 相比原生的PHP, 几乎不会带来额外的性能开销. 所有的框架类, 不需要编译, 在PHP启动的时候加载, 并常驻内存. 更短的内存周转周期, 提高内存利用率, 降低内存占用率. 支持全局和局部两种加载规则, 方便类库共享.

微服务框架-基础框架

- - 人月神话的BLOG
上面一篇文章对SpringBoot框架做了一下简单验证,在文中也写到SpringBoot重点还是在单个微服务模块的开发,已经对于微服务接口开放的便捷性上,而对于微服务基础架构和管控治理层面没有太多支持. 对于微服务基础框架可以看作是微服务治理架构的核心内容,包括了对微服务模块的全生命周期管理能力,这个能力包括了微服务网关APP,DevOps,Docker和云集成,安全,负载均衡,服务注册和发现等诸多能力.

Shiro权限框架

- If you are thinking one year ahead, you plant rice. If you are thinking twenty years ahead, you plant trees. If you are thinking a hundred years ahead, you educate people. - BlogJava-首页技术区
开发系统中,少不了权限,目前java里的权限框架有SpringSecurity和Shiro(以前叫做jsecurity),对于SpringSecurity:功能太过强大以至于功能比较分散,使用起来也比较复杂,跟Spring结合的比较好. 对于初学Spring Security者来说,曲线还是较大,需要深入学习其源码和框架,配置起来也需要费比较大的力气,扩展性也不是特别强.

Pyramid 框架介绍

- Ken - python.cn(jobs, news)
来自 易度云办公 - 潘俊勇(http://weibo.com/panjunyong). [北京] 招聘Python高级工程师 - 创业公司. [武汉] Perl软件工程师(高新急聘) - 赛诺(武汉)技术有限公司. [武汉] 云存储软件研发工程师(高新急聘) - 赛诺(武汉)技术有限公司. [北京] Python核心研发 - 北京尚学硕博教育咨询.

J.U.C并发框架

- - 并发编程网 - ifeve.com
作者:Doug Lea. 在J2SE1.5中,java.util.concurrent包下的大部分同步工具(锁、屏障等)以AbstractQueuedSynchronizer类为基础来构建. 这个框架提供了一些常用机制用于自动管理并发状态、阻塞及非阻塞线程,以及队列. 本论文描述了该框架的根源、设计、实现、用法及性能.

[转] jQuery ui框架

- - CSDN博客Web前端推荐文章
   jQuery ui框架很多,除了官方提供的 jquery UI(如果你还不知道什么是 jQuery UI,请看 下载了jquery ui后如何使用),还有很多第三方提供的ui框架,因官方提供的jquery ui框架体积较大,所以很多人都不喜欢用,但不论是官方提供还是第三方提供,他们都是基于 jquery核心类库实现的ui框架.

UI框架选型

- - ITeye博客
  最近公司的一个新项目要进行UI框架的选型,我把选型的思路和过程跟大家分享一下.   在选型之前,我们先要定一下选型的标准,就像人生一样,想清楚“自己要的是什么”是最重要的.   选型的标准分为几部分:. 业务是根本,和大部分的技术一样,框架没有好坏之分,只有适合与不适合.         我们项目是一个通讯类的监控项目,用户群是移动、电信等运营商的运维人员,系统的特点是:.

springmvc框架配置

- - CSDN博客编程语言推荐文章
. . .

nginx框架总结

- - CSDN博客互联网推荐文章
a、内存池的设计,为一个多级链表结构,本身不负责内存的回收,减少内存碎片,提高内存的利用率,将多次向操作系统申请内存压缩为一次,减少向操作系统申请内存的次数,提高cpu资源的利用;. b、基于事件的master-worker异步处理. 处理事件的机制是由事件分发进程加载事件处理模块来完成与传统将事件提交给handle-thread来处理的方式相比,减少了进程(线程)间的切换,从而降低了请求响应延迟的时间;.