如何有效避免大量重复的switch分支

新浪微博 QQ空间

最近学习设计模式相关知识,结合前面的DRBD源码分析掌握了表驱动编程模式,这里作一些简单的总结。

先看一段C代码:

typedef int type;
typedef void(*draw)(void); 

struct shape
{
    type t;
    draw f;
};

struct rectange
{
    type t;
    int a;
    draw f;
};

struct circle
{
    type t;
    int r;
    draw f;
};

#define T1 0
#define T2 1
#define T3 2

void drawall(shape[] s, int count)
{
    for (int i = 0; i != count; i++)
    {
        switch((s + i)->t)
        {
        case T1:
            ((struct shape*)(s + i))->f();
            break;
        case T2:
            ((struct rectange*)(s + i))->f();
            break;
        case T3:
            ((struct circle*)(s + i))->f();
            break;
        default:
            break;
        }
    }
}

 

代码中需要根据图形的形状去调用具体的draw方法,对type的判断只是为了确定该调用哪个结构体中的draw类型的函数。那么能否简化一下这个switch case呢?最简单的,修改各个抽象形状的结构体定义,然后定义一个共有的“基类”,即只定义类型和函数指针,将各种形状对象强转为“基类型”,然后统一调用函数指针即可,同时可以将指向形状对象的基类指针作为参数传入,在函数中再将基类型的指针转为具体的子类兴。达到去除case switch的目的。

按照如上思路修改之后的代码应该是类似这样的:

struct base
{
    type t;
    draw f;
};

typedef int type;
typedef void(*draw)(struct base*); 

struct shape
{
    type t;
    draw f;
};

struct rectange
{
    type t;
    draw f;
    int a;
};

struct circle
{
    type t;
    draw f;
    int r;
};

#define T1 0
#define T2 1
#define T3 2

void drawall(struct base[] s, int count)
{
    struct base* b = s;
    for (int i = 0; i != count; i++)
    {
        (b + i)->draw(b + i);
    }
}

 

这样,要求所有的类型都应该“符合”base类型的结构,当出现不符合该类型的结构传入时,编译时并不会报错,运行时才会寻址错误。这样做不是特别好。

按照表驱动模式进一步改造该代码:

struct config
{
    type t;
    int l;
};

typedef int type;
typedef void(*draw)(struct config*); 

void drawshape(struct config*);
void drawsrectange(struct config*);
void drawcircle(struct config*);

#define T1 0
#define T2 1
#define T3 2

draw call_table[] = {
    [T1] = {&drawshape},
    [T2] = {&drawsrectange},
    [T3] = {&drawcircle},
};

void drawall(struct config[] s, int count)
{
    draw* d = call_table;
    struct config* b = s;
    for (int i = 0; i != count; i++)
    {
        (*(d + (b + i)->t))(b + i);
    }
}

 

这样代码看起来是简洁了,但是可读性降低了不少。

新浪微博 QQ空间

| 1 分2 分3 分4 分5 分 (5.00- 5票) Loading ... Loading ... | 这篇文章归档在:语言基础, 软件技术 | 标签: , . | 永久链接:链接 | 评论(0) |

评论

邮箱地址不会被泄露, 标记为 * 的项目必填。

8 - 2 = *



You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <img alt="" src="" class=""> <pre class=""> <q cite=""> <s> <strike> <strong>

返回顶部