废话不说,看代码:
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
》声称这个是表驱动法。
表驱动法就是将一些通过较为复杂逻辑语句来得到数据信息的方式,通过查询表的方式来实现,将数据信息存放在表里。
这样不仅代码看起来简明,而且后面如果数据或者别的什么改变的话维护起来也相对简单。
比如,将上面的
ajlb
和
jtdw
存储到类似的一个表的结构中(如
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);
}
表驱动的好处是消除代码里面到处出现的
if
、
else
、
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.
提取出键值转换函数来,单独的函数来处理表的键值生成