本文首发于 http://www.YoungZY.com/
现在需要你提供这样一个函数:获得指定月份的天数(为了方便讨论,忽略闰年)。你会怎么做?
大概率是这样的:
大概率是这样的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
func DaysOfMonthGeneral(month int) int { switch month { case 1: return 31 case 2: return 28 case 3: return 31 case 4: return 30 case 5: return 31 case 6: return 30 case 7: return 31 case 8: return 31 case 9: return 30 case 10: return 31 case 11: return 30 case 12: return 31 default: panic("invalid month") } } |
而表驱动开发则是这样的:
1 2 3 4 5 |
var daysPerMonth = []int{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} func DaysOfMonth(month int) int { return daysPerMonth[month-1] } |
这个例子太简单?那再看个例子。
根据分数得到等级。
分数 | 等级 |
---|---|
>=90 | A |
<90 | B |
<75 | C |
<65 | D |
<50 | F |
你很可能会这么做:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
func GetGradeGeneral(score float32) string { if score >= 90.0 { return "A" } else if score >= 75.0 { return "B" } else if score >= 65.0 { return "C" } else if score >= 50.0 { return "D" } else { return "F" } } |
有没有更灵活的方式呢?
有的,还是表驱动法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
var ( rangeUpper = []float32{50.0, 65.0, 75.0, 90.0, 100.0} grades = []string{"F", "D", "C", "B", "A"} ) // GetGrade 表驱动法 func GetGrade(score float32) string { maxGradeLevel := len(grades) - 1 gradeLevel := 0 studentGrade := "A" // 数据量大时可考虑二分查找 for studentGrade == "A" && gradeLevel < maxGradeLevel { if score < rangeUpper[gradeLevel] { studentGrade = grades[gradeLevel] } gradeLevel++ } return studentGrade } |
总结
表驱动,就是把复杂的条件分支或运算逻辑转移到对“表”的访问上。
这里说的“表”和数据库中的表没有关系,更像是一张表格或者容器。通常可以用数组或者Map实现。
加入讨论