C++的表驱动法

 

 C++的表驱动法

目的:使用表驱动法,替换复杂的if/else和switch/case语句。

 一、常用示例

 以switch为例,常用示例如下:

Funcition()
{
    switch (key)
    {
        case key1:
            statements 1;
            break;
        case key2:
            statements 2;
            break;
        ... 
        case keyn:
            statements n;
            break;
        default:
            break;
    }
}

 

上述switch代码段,实际集成了3种类型逻辑:

1.    实现关键字的处理代码;

2.    将关键字与处理代码关联;

3.    以关键字选择分支,执行处理代码;

我们将在一个switch代码中维护3种变化。将1的处理代码段,模块化为函数后,变化点减少为2个。

在分支增加到几十个时,代码维护性变得很差;而且switch对非整数类型无能为力。

 二、表驱动法

做法:

1.  将变化点2,做成一个[关键字:处理函数]映射结构(推荐map容器),在独立函数中赋值。

2.  将变化点3,做成一个查找关键字,执行对应函数的简单函数。

好处:

1.  独立出“选择分支”变化点,变为固定的处理流程。

2.  独立出“关键字和处理函数的关联”,易于维护。

限制条件

1.  处理函数类型一样(这在C++中不成问题);

2.  处理函数简单,但每个函数有差异(如果处理较为复杂,请使用创建型设计模式)

扩展

1.  对于处理函数由符合条件分支情况,变化点2使用list结构,按优先级关联处理函数,使用 “职责链”形式的表驱动法。

 三、C++实现注意

代码

参见 C++表驱动法代码示例。

关注点

主要关注3个点,维护第2、3点

1.   HandleKeyword(),根据关键字,执行处理函数。固定后基本不改变;

2.   MapKeyToHandle(),关联关键字到处理函数;

3.   Handle(),各个处理函数

成员函数指针使用注意

1.  声明格式,与C相比,函数指针前要包含类域;

            typedef bool (TableDrive:: *PHandle)();

2.  声明位置,包含在类中,否则不能识别类域标志;

3.  赋值语法格式,与C相比,函数指针前要包含类域;

           PHandle pFunction = &TableDrive::HandleKeyA;

4.  调用语法格式,与C相比,需要加上this,并以强制解引用方式调用;

           (this->*pFunction)();

 四、实用案例

1.  菜单调节。一个模块,有几十个菜单参数可以调节,每个菜单调节的步进、范围不同,但都是“触发消息、调节数值”流程。

2.  按键响应。多个按键,属于“按键,执行对应处理函数”流程。

3.  鼠标操控。不同状态下移动鼠标,属于“状态判断、响应鼠标处理函数”流程。

 

参考资料

1. 《代码大全》(第2版)中文版,第18章 表驱动法。

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值