另載於 http://www.qingjingjie.com/blogs/8程序員
前段時間知乎上有人發了這麼個段子:算法
某日,老師在課堂上想考考學生們的智商,就問一個男孩: 「樹上有十隻鳥,開槍打死一隻,還剩幾隻?」 男孩反問:「是無聲手槍,仍是其餘沒有聲音的槍麼?」 「不是.」 「槍聲有多大?」 「80~100分貝.」 「那就是說會震的耳朵疼?」 「是.」 「在這個城市裏打鳥犯不犯法?」 ‘不犯.」 「您肯定那隻鳥真的被打死啦?」 「肯定.」老師已經不耐煩了,」拜託,你告訴我還剩幾隻就好了,OK?」 「OK.鳥裏有沒有聾子?」 「沒有.」 「有沒有鳥智力有問題,呆傻到聽到槍響不知道飛的?」 「沒有,智商都在200以上!」 「有沒有關在籠子裏的?」 「沒有.」 「邊上還有沒有其餘的樹,樹上還有沒有其餘鳥?」 「沒有.」 「方圓十里呢?」 「就這麼一棵樹!」 「有沒有殘疾或餓的飛不動的鳥?」 「沒有,都身體倍棒.」 「算不算懷孕肚子裏的小鳥?」 「都是公的.」 「都不可能懷孕?」 「………,決不可能.」 「打鳥的人眼裏有沒有花?保證是十隻?」 「沒有花,就十隻.」 老師腦門上的汗已經流下來了, 下課鈴響起,但男孩仍繼續問:「有沒有傻的不怕死的?」 「都怕死.」 「有沒有由於情侶被打中,本身留下來的?」 「笨蛋,以前不是說都是公的嘛!」 「**可不能夠啊!」 「………….,性取向都很正常!」 「會不會一槍打死兩隻?」 「不會.」 「一槍打死三隻呢?」 「不會.」 「四隻呢?」 「更不會!」 「五隻呢?」 「絕對不會!!!」 「那六隻總有可能吧?」 「除非你他媽的是豬生的纔有可能!一槍只能打死一隻!」 「…好吧,那麼全部的鳥均可以自由活動麼?」 「徹底能夠.」 「它們受到驚嚇起飛時會不會惶恐不安而互相撞上?」 「不會,每隻鳥都裝有衛星導航系統,並且能夠自動飛行.」 「恩,若是您的回答沒有騙人,」學生滿懷信心的回答,「打死的鳥要是掛在樹上沒掉下來,那麼就剩一隻,若是掉下來,就一隻不剩.」 老師推推眼鏡,強忍着要昏倒的感受,顫抖地說道:「你能夠去當程序員了……」
有人就在下面問怎麼寫代碼才能避免一連串的if else?設計模式
由於他用Python,我就回答:把每個條件判斷都寫成一個布爾函數,把這些函數依次放進一個數組/列表。再寫一個函數來遍歷數組,對每一項,若爲假則返回,若爲真則繼續。數組
對Java(8以前)來講,沒有一等函數,就要把每一個條件判斷寫成Function接口的實現類。app
而用Java 8來寫,就是:函數
Collection<Function<Context, Boolean>> conditions = new ArrayList<>(); conditions.add(context -> isGunSilent(context)); conditions.add(context -> isGunSoundBig(context)); conditions.add(context -> isShootingBirdLegal(context)); ... public boolean judge(Context context, Collection<Function<Context, Boolean>> conditions) { for (Function<Context, Boolean> cond : conditions) { if (!cond.apply(context)) { return false; } } return true; }
Context是個包裝類,包含了gun, city, bird, tree等數據。設計
折騰以後,代碼量相比一連串if else略有減小,彷佛收益不大?噢,值得注意的是,這種方法具備高度的靈活性!code
這些條件能夠提早定義好,而後處處複用!你能夠任意地組合它們,來構造一段業務邏輯,只須要挑選你要的條件,塞到一個list裏面!簡直棒!blog
這是用了哪一種設計模式呢,比較像Strategy,我認爲還像Template Method: 定義一個操做中的算法的骨架,而將一些步驟延遲到子類中。
咱們定義了做爲骨架的judge():for循環,遇到false停止。而後在把步驟在子類中實現(雖然與judge()不屬於同一個父類)。
雖然結構跟書上不同,可是有相同的精神。接口
Chain of Responsibility須要先後連接,節點對其後的子鏈有控制力,因此不那麼像。