Chinaunix首页 | 论坛 | 博客
  • 博客访问: 133469
  • 博文数量: 27
  • 博客积分: 681
  • 博客等级: 上士
  • 技术积分: 257
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-07 16:07
文章分类

全部博文(27)

文章存档

2012年(8)

2011年(16)

2010年(3)

分类:

2011-06-13 09:03:58

原文地址:表驱动法 作者:q_T_p

驱动表不是什么高深的东西,在《代码大全2》中有详细的讲解。

    看一个简单的例子:
    
    2012过去了,仅存的人类从事原始的生产劳作,以集体为单位。很不幸2013年人类生产食物的总和有限,不得不根据对象的

特点进行食物的分配。最初的规则如下:

    20岁以上的男人,每人分配100斤食物
    
    20岁以下的男人,每人分配80斤食物
  
    20岁以上的女人,每人分配80斤食物

    20岁以下的女人,每人分配60斤食物

    于是你写了如下的代码

    int getFood(bool isMan,bool ageMoreThan20)
    {
if(isMan)
{
if( ageMoreThan20)
{
return 100;
}
else
{
return 80;
}
}
else
{
if( ageMoreThan20)
{
return 80;
}
else
{
return 60;
}
}
     }    

     于是你很满意,因为你圆满完成了人类食物的分配工作,保证了大家尽块可能吃饱。但是突然,一群大胖子找到了

把你狠揍你一顿,最后你搞明白了,原来这样的分配方式让他们吃不饱。你很自责与愧疚,于是要改这个算法,增加了

这样的规则:

     20岁以上的男胖子120斤
     20岁以下的男胖子100斤
     20岁以上的女胖子100斤
     20岁以下的女胖子80斤

代码就变成了这样
    
    int getFood(bool isMan,bool ageMoreThan20,bool isFatMan)
    {
if(isMan)
{
if( ageMoreThan20)
{
if(isFatMan)
{
return 120;
}
else
{
return 100;
}
}
else
{
if(isFatMan)
{
return 100;
}
else
{
return 80;
}
}
}
else
{
if( ageMoreThan20)
{
if(isFatMan)
{
return 100;
}
else
{
return 80;
}
}
else
{
if(isFatMan)
{
return 80;
}
else
{
return 60;
}
}
}
     }  
      

写完这段代码,你揉着太阳穴,并感到莫名的紧张和不安,为啥呢?你看到太多的if else;看到太多的代码;同时你想到

了代码的可读性、可维护性、可扩展性。“擦,下次再增加一个判断因子的话。。。。”

代码大全告诉我们,当遇到太多if else,已经深成的嵌套的时候,你应该告诉自己,coder就应该对自己狠一点,把现有的

的代码删除吧,用驱动表吧,这才能拯救人类。


驱动表:其实就是一个多维数组,他的维数由变项的数量决定,如果变项为3,则是一个3维数组,每个元素值代表着3种变项

的一种具体的组合对应的值;这样我们就把对if else的维护,变成了对数组的维护。代码可以是这样。


int val[2][2][2];

该数组的一维代表性别,0为男人,1为女人
该数组的二维代表年龄,0为大于20,1小于20岁
该数组的三维代表是否是胖子,0为是胖子,1代表不是胖子

所以val[0][0][0]=120表示20岁以上的男胖子分配120斤食物。



对这个数组的8个值进行初始化

int getFood(bool isMan,bool ageMoreThan20,bool isFatMan)
{
return val[isMan][ageMoreThan20][isFatMan];
}


驱动表的优点在于:

1,维护数组比维护if else容易
2, 代码简洁
3,性能高(直接是偏移地址的运算)


驱动表实际是一个值的存取和访问,这个值可以是一个具体的值、一个处理方法的引用、一个对象。而对这个值的访问

可以是直接寻址,如例子所示、也可以是索引(key值为字符串)、也可以是阶梯形式。
阅读(2483) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~