代碼大全2 - 表驅動法

最近入手了 代碼大全2,真實程序員的聖經啊,內容好高端啊,書中建議的初級程序員看的章節就是:表驅動法,真 NM NB,聽都沒聽過,可是很是有用,其想法絕對不是一我的經過自我學習能醒悟出來的python

表驅動法 的思路是什麼:用表來代替那些 if/else 的業務邏輯,你把業務邏輯寫在 if/else 裏就是硬編碼,可是寫到表裏是能夠實現功能分離的,邏輯表能夠統一作路徑設置或者其餘配置,這樣的話業務邏輯會變得很是容易閱讀和理解了程序員

我不說原理,書光說原理了,有限的代碼仍是 VB 的,壓根無法看,因此我給你們舉些例子,你們看代碼體會,思想得落地才能變成本身的數組


今天周幾

像幾天周幾這樣的,其實最適合作表驅動了,由於邏輯最清晰,簡單,一個數組+下標,輕輕鬆鬆搞定bash

傳統寫法:函數

String today = "週日";
Switch( dayForMonth % 7 ){
    case 0 : 
        today = "週日";
    case 1 : 
        today = "週一";   
    case 2 :
        today = "週二";   
    case 3 :
        today = "週三";   
    case 4 :
        today = "週四";   
    case 5 :
        today = "週五";   
    default:
        today = "週六";   
}
複製代碼

表驅動法學習

String [] weekday = new String[]{"週日","週一","週二","週三","週四","週五","週六"};
String today = weekday [ dayForMonth % 7 ];
複製代碼

每月對應多少天

傳統的寫法,咱們要寫一串 if/else 返回數據ui

傳統寫法:編碼

if(1 == iMonth) {iDays = 31;}
  else if(2 == iMonth) {iDays = 28;}
  else if(3 == iMonth) {iDays = 31;}
  else if(4 == iMonth) {iDays = 30;}
  else if(5 == iMonth) {iDays = 31;}
  else if(6 == iMonth) {iDays = 30;}
  else if(7 == iMonth) {iDays = 31;}
  else if(8 == iMonth) {iDays = 31;}
  else if(9 == iMonth) {iDays = 30;}
  else if(10 == iMonth) {iDays = 31;}
  else if(11 == iMonth) {iDays = 30;}
  else if(12 == iMonth) {iDays = 31;}
複製代碼

可是表驅動法就不同了,把邏輯寫成 map 或是 list,一目瞭然,這裏咱們搞個2維數組還加上了閏年的邏輯spa

表驅動法code

const monthDays = [
  [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
  [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
]

function getMonthDays(month, year) {
  let isLeapYear = (year % 4 === 0) && (year % 100 !== 0 || year % 400 === 0) ? 1 : 0
  return monthDays[isLeapYear][(month - 1)];
}

console.log(getMonthDays(2, 2000))
複製代碼

不一樣條件執行不一樣任務

由於是任務,是個方法,再也不是數值了,這裏咱們能夠利用 Dart 這樣的支持高階函數的語言特性,把方法當作一個對象存儲在表中

表驅動法

var data = <String, Map>{
    "A": {
      "name": "AA",
      "action": (name) => print(name + "/AA"),
    },
    "B": {
      "name": "BB",
      "action": (name) => print(name + "/BB"),
    },
  };
  
  var action = data["A"]["action"];
  action("kk");
  
  // if( action is Function ) action("KK");
複製代碼

action 可能會包紅線,提示不是方法類型,你們強轉一下就好了。這個內部能夠無限的往下一層層嵌套,只要保證是 map 的就能經過[]統一書寫調用了


加減法

加法和減法有不一樣的計算共公式,那麼就像下面這樣寫,抽象方法當作對象使用,存到 map 表裏去

傳統寫法:

def test(c,a,b):
    if c == '+':
        return a + b
    elif c == '-':
        return a - b
複製代碼

表驅動法:

def add(a,b):
    return a+b

def minus(a,b):
    return a - b

func_dict = {'+':add,'-':minus}
print(func_dict['+'](1,2))
複製代碼

複雜多條件判斷

這個例子邏輯最複雜,由於判斷的條件多,而且還有不一樣配置,像這種問題,咱們通常用2維數組來作,x 軸是判斷條件,y 軸是不一樣配置

傳統寫法:

if( (a && !c ) || (a && b && c)){
    category = 1 ;     
}else if( (b && ! a) || (a && c && !b)){
    category = 2 ;     
}else if ( c && !a && !b){
    category = 3 ;     
}else {
    category = 0 ;     
}
複製代碼

表驅動法:

// 把邏輯變爲 2維數組,作好註釋,這樣看是否是很清晰啊
static int categoryTable[2][2]={
    //!b!c   !bc   b!c   bc
        0,   3,     2,    2, // !a    
        1,   2,     1,    1, // a
}
// 使用
category = categoryTable[1][0];
複製代碼

帶取值範圍的

像某某範圍內是啥這樣的,咱們取兩邊的端點數值做爲依據,在數值判斷時使用最簡單的方式:for 循環

  • 0-59 分是不及格 F級
  • 60- 79 是及格 E級
  • 80-84 是普通 D級
  • 85-89 是良好 C級
  • 90 - 94 是優秀 B級
  • 95-100 是太棒了 A級

表驅動法:

int [] grade = {59,79,84,89,94,100}; 
String [] level = {"F","E","D","C","B","A"},

public String getLevel (int grade){
    for( int i = 0 ; i < grade.length ; i++){
        if(grade <= grade[i]){
            return  level[i];
        }
    }
}
複製代碼
相關文章
相關標籤/搜索