`

表驱动法Table-Driven Methods

 
阅读更多

表驱动法是一种编程模式----从表里面查找信息而不适用逻辑语句(if和case)。

表提供了一种复杂的逻辑和继承结构的替换方案。如果你发现自己对某个应用程序的逻辑或者继承树关系感到困惑,那么问问自己它是否可以通过一个查询表来加以简化。

使用表的一项关键决策是决定如何去访问表。你可以采取直接访问、索引访问或者阶梯访问。

使用表的另一项关键决策是决定应该把什么内容放入表中。

下面是个例子:

原文地址表驱动法  

 

驱动表不是什么高深的东西,在《代码大全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值为字符串)、也可以是阶梯形式。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics