代碼大全2 - 表驅(qū)動法

image

最近入手了 代碼大全2厌殉,真實程序員的圣經(jīng)啊胡桃,內(nèi)容好高端啊踩叭,書中建議的初級程序員看的章節(jié)就是:表驅(qū)動法,真 NM NB翠胰,聽都沒聽過容贝,但是非常有用,其想法絕對不是一個人通過自我學(xué)習(xí)能醒悟出來的

表驅(qū)動法 的思路是什么:用表來代替那些 if/else 的業(yè)務(wù)邏輯之景,你把業(yè)務(wù)邏輯寫在 if/else 里就是硬編碼斤富,但是寫到表里是可以實現(xiàn)功能分離的,邏輯表可以統(tǒng)一做路徑設(shè)置或者其他配置锻狗,這樣的話業(yè)務(wù)邏輯會變得非常容易閱讀和理解了

我不說原理满力,書光說原理了焕参,有限的代碼還是 VB 的,壓根沒法看油额,所以我給大家舉些例子叠纷,大家看代碼體會,思想得落地才能變成自己的


今天周幾

像幾天周幾這樣的潦嘶,其實最適合做表驅(qū)動了涩嚣,因為邏輯最清晰,簡單掂僵,一個數(shù)組+下標(biāo)缓艳,輕輕松松搞定

傳統(tǒng)寫法:

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 = "周六";   
}

表驅(qū)動法

String [] weekday = new String[]{"周日","周一","周二","周三","周四","周五","周六"};
String today = weekday [ dayForMonth % 7 ];

每個月對應(yīng)多少天

傳統(tǒng)的寫法,我們要寫一串 if/else 返回數(shù)據(jù)

傳統(tǒng)寫法:

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;}

但是表驅(qū)動法就不一樣了看峻,把邏輯寫成 map 或是 list阶淘,一目了然,這里我們搞個2維數(shù)組還加上了閏年的邏輯

表驅(qū)動法

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))

不同條件執(zhí)行不同任務(wù)

因為是任務(wù)互妓,是個方法溪窒,不再是數(shù)值了,這里我們可以利用 Dart 這樣的支持高階函數(shù)的語言特性冯勉,把方法當(dāng)做一個對象存儲在表中

表驅(qū)動法

  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 可能會包紅線澈蚌,提示不是方法類型,大家強轉(zhuǎn)一下就行了灼狰。這個內(nèi)部可以無限的往下一層層嵌套宛瞄,只要保證是 map 的就能通過[]統(tǒng)一書寫調(diào)用了


加減法

加法和減法有不同的計算共公式,那么就像下面這樣寫交胚,抽象方法當(dāng)做對象使用份汗,存到 map 表里去

傳統(tǒng)寫法:

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

表驅(qū)動法:

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

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

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

復(fù)雜多條件判斷

這個例子邏輯最復(fù)雜,因為判斷的條件多蝴簇,并且還有不同配置杯活,像這種問題,我們一般用2維數(shù)組來做熬词,x 軸是判斷條件旁钧,y 軸是不同配置

傳統(tǒng)寫法:

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 ;     
}

表驅(qū)動法:

// 把邏輯變?yōu)?2維數(shù)組,做好注釋互拾,這樣看是不是很清晰啊
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];

帶取值范圍的

像某某范圍內(nèi)是啥這樣的歪今,我們?nèi)蛇叺亩它c數(shù)值作為依據(jù),在數(shù)值判斷時使用最簡單的方式:for 循環(huán)

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

表驅(qū)動法:

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];
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末颜矿,一起剝皮案震驚了整個濱河市寄猩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌或衡,老刑警劉巖焦影,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件车遂,死亡現(xiàn)場離奇詭異,居然都是意外死亡斯辰,警方通過查閱死者的電腦和手機舶担,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來彬呻,“玉大人衣陶,你說我怎么就攤上這事≌⒌” “怎么了剪况?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蒲跨。 經(jīng)常有香客問我译断,道長,這世上最難降的妖魔是什么或悲? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任孙咪,我火速辦了婚禮,結(jié)果婚禮上巡语,老公的妹妹穿的比我還像新娘翎蹈。我一直安慰自己,他們只是感情好男公,可當(dāng)我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布荤堪。 她就那樣靜靜地躺著,像睡著了一般枢赔。 火紅的嫁衣襯著肌膚如雪澄阳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天糠爬,我揣著相機與錄音寇荧,去河邊找鬼。 笑死执隧,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的户侥。 我是一名探鬼主播镀琉,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蕊唐!你這毒婦竟也來了屋摔?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤替梨,失蹤者是張志新(化名)和其女友劉穎钓试,沒想到半個月后装黑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡弓熏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年恋谭,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挽鞠。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡疚颊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出信认,到底是詐尸還是另有隱情材义,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布嫁赏,位于F島的核電站其掂,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏潦蝇。R本人自食惡果不足惜款熬,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望护蝶。 院中可真熱鬧华烟,春花似錦、人聲如沸持灰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽堤魁。三九已至喂链,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間妥泉,已是汗流浹背椭微。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留盲链,地道東北人蝇率。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像刽沾,于是被迫代替她去往敵國和親本慕。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,037評論 2 355