`
雪飘寒
  • 浏览: 30106 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

使用表驱动简化复杂逻辑判断

 
阅读更多

 

废话不说,看代码:
 if (jtdw == 1 || jtdw == 2 || jtdw == 7 || jtdw == 8 || jtdw == 15
                || jtdw == 19 || jtdw == 20 || jtdw == 21) {
            ajlb = 1;
        } else if (jtdw == 3 || jtdw == 4 || jtdw == 5 || jtdw == 6
                || jtdw == 16) { // 2008-04-16 add 16
            ajlb = 2;
        } else if (jtdw == 17) {
            ajlb = 6;
        } else if (jtdw == 9) {
            ajlb = 8;
        } else if (jtdw == 13 || jtdw == 18) {
            ajlb = 13;
        } else if (jtdw == 10 || jtdw == 22) {
            ajlb = 11;
        } else if (jtdw == 23) { // 2009-12-1 对于立案二庭的案件,点击节点
            ajlb = 2;
        } else {
            ajlb = 12;
        }
      
这段代码在程序中出现了多次,基本就是有些地方多出来一个判断,有些地方少了一个判断而已,应该提取成公共的方法,简化代码,方便复用。这不是主要问题,主要问题在于:
 
1. 代码太长,难理解:不解释。
2. 可维护性低:比如里面两个有注释的地方,都是后期添加的,以后修改或增加的判断多了,都会使现有的程序更难理解。
 
其实,这种情况在程序中出现很频繁,在我们的系统中出现的更是频繁。应对这种复杂的逻辑判断有很多很多方法,这里介绍一种叫做表驱动的方法。
 
人类阅读复杂数据结构远比复杂的控制流程容易,或者说数据驱动开发是非常有价值的。
《代码大全 2》声称这个是表驱动法。
 
表驱动法就是将一些通过较为复杂逻辑语句来得到数据信息的方式,通过查询表的方式来实现,将数据信息存放在表里。 
这样不仅代码看起来简明,而且后面如果数据或者别的什么改变的话维护起来也相对简单。
比如,将上面的 ajlbjtdw 存储到类似的一个表的结构中(如 Map),业务逻辑中只需
ajlb = getAjlbByJtdw(jtdw);
 
就可以替换原来的很多行的判断,以后修改时,只需在 map中添加一个即可,不影响业务逻辑流程。
 
   private static Map<Integer, Integer> JTDW_AJLB = new HashMap<Integer, Integer>();
    static {
        JTDW_AJLB.put(1, 1);//注释
        JTDW_AJLB.put(2, 1);
        JTDW_AJLB.put(7, 1);
        JTDW_AJLB.put(8, 1);
      .........
    }
    public static int getAjlbByJtdw(int jtdw) {
        return JTDW_AJLB.get(jtdw);
    }
 
 
表驱动的好处是消除代码里面到处出现的 ifelse swith语句,让凌乱代码变得简明和清晰。对简单情况而言,表驱动方法可能仅仅使逻辑语句更容易和直白,但随着逻辑的越来越复杂,表驱动法就愈发有吸引力。
 
补充解释一下表驱动方法:
使用表驱动的主要要明白:如何构建表确定什么样的规则来访问表里的数据。
表驱动的访问方式主要有三种: 直接访问、索引访问、阶梯访问。
 
1. 直接访问:key value格式


 
经典的例子,根据月份取天数,非常好理解、不解释,看代码:
   
 public int getMonthDays(int month) {
        int days = 0;
        if (1 == month) {
            days = 31;
        } else if (2 == month) {
            days = 28;
        } else if (3 == month) {
            days = 31;
        } else if (4 == month) {
            days = 30;
        } else if (5 == month) {
            days = 31;
        } else if (6 == month) {
            days = 30;
        } else if (7 == month) {
            days = 31;
        } else if (8 == month) {
            days = 31;
        } else if (9 == month) {
            days = 30;
        } else if (10 == month) {
            days = 31;
        } else if (11 == month) {
            days = 30;
        } else if (12 == month) {
            days = 31;
        }
        return days;
    }
 
使用表驱动的直接访问方式消除 if语句
   
 private static int MONTH_DYAS[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31,30, 31 };

    public int getMonthDays(int month) {
        return MONTH_DYAS[(month - 1)];
    }
 
 
2. 索引访问


 
这种方式用于解决嵌套的 if效果比较明显,比如Map<String,Map<String,String>>,外层Map 存储内层 Map的索引,内层Map存储值,就不用代码举例了。
 
3. 阶梯访问,主要适用于无规则数据。比如在某个范围区间内,对应某个值。这里就不用代码举例了。


 
 
表驱动好处:
1. 在适当环境下,使用它能够使代码简单、明了。
    2. 修改容易(易维护)、效率更高。
    3. 表驱动法的一个好处就是能够大量消除代码中 if - else swith 判断。
缺点:这是一个用数据结构替换复杂流程控制的方法, 某些情况下 浪费空间,有时查找可能没有直接判断快,效率低。
 
   表驱动的一个很重要的问题是如何去构建查询的键值。主要有以下几种方式:
1. 直接使用有规则的数据作为键值
2. 赋值信息从而能够直接使用键值
3. 在特定情况下写代码转换键值使其能够直接使用
4. 提取出键值转换函数来,单独的函数来处理表的键值生成
 
  
  • 大小: 14.7 KB
  • 大小: 47.3 KB
  • 大小: 24.6 KB
3
2
分享到:
评论
2 楼 AliceHR520 2013-03-01  
学习了
1 楼 chinaagan 2013-02-28  
代码大全?

相关推荐

Global site tag (gtag.js) - Google Analytics