iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 29
1
自我挑戰組

再戰軟體工程系列 第 28

『珍惜生命,遠離波動拳』 -- 從壞習慣談程式可讀性

程式可讀性要高,這件事大家都知道,但是真正能做到的有幾個?在工作中,當你在撰寫一個功能時,因為你的心思全心全意都放在你的邏輯裡,你不是一個『隨便拿以前的code複製貼上就交差』的人...(吧?),所以妳寫出來的程式脈絡,不管怎麼看都是合理的。然而,別人怎麼看呢?不知道?你隨便拿一個同組的同事的code起來看看就能體會啦

我們在前文中提過,『寫出機器看得懂的code很簡單。compile能過機器就看得懂,寫出人類看得懂的才是真功夫。』本文從另一個角度出發,如果你遇到一個邏輯比較複雜,條件比較多的判斷式,你應該怎麼寫出人類比較看得懂的程式,降低別人閱讀你的程式碼時的『WTF/min』率。

wtf/min


我們來看看範例吧!這個範例超簡單。我有一個妹妹,他想要交男朋友,於是就列出他的擇偶條件如下:
https://ithelp.ithome.com.tw/upload/images/20171217/20107429BbuoQ0RLJC.png

我就很熱心的幫他把這樣的條件寫成判斷式:

public boolean isOKAdai(boolean isReach, int facePoint,
                            boolean hasHouse, boolean hasCar,
                            boolean isPhD, long income,
                            boolean isPlayBoy, boolean isFunny, boolean hasHumor, boolean isGentle){
        if (isReach && facePoint > 90 && hasHouse && hasCar && isPhD && income > 3000000
                && !isPlayBoy && isFunny && hasHumor && isGentle){
            return true;
        } else {
            return false;
        }
    }

看得很痛苦吧?如果你感到痛苦,恭喜你有一雙正常人的眼睛。這樣的程式寫法只有機器看得懂,人類是看得很痛苦的。於是,一些比較有經驗的RD就發現,幫他們分些層次,比較能提高可讀性。為了分出層次,著名的波動拳就出現了:

 public boolean isOKHadouken(boolean isRich, int facePoint,
                                boolean hasHouse, boolean hasCar,
                                boolean isPhD, long income,
                                boolean isPlayBoy, boolean isFunny, boolean hasHumor,
                                boolean isGentle) {

        if (isRich) {
            if (facePoint > 90) {
                if (hasHouse) {
                    if (hasCar) {
                        if (isPhD) {
                            if (income > 3000000) {
                                if (!isPlayBoy) {
                                    if (isFunny) {
                                        if (hasHumor) {
                                            if (isGentle) {
                                                return true;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return false;
    }

這樣的波動拳是否在你的專案中經常出現?如果是,那你要小心了。為什麽?因為,上面的例子是非常簡單的,但是在工作中常出現的其實比較像:『沒有初沒關係,只要不花心就好。』、『萬一是個花心男,那至少要有錢,不然就是要體貼
。』、『如果不體貼,那一定要有錢,或者是高學歷且幽默』...等複雜狀況。那麼,你的波動拳就沒有辦法像上面這麼順暢了。他應該會呈現『大波中有小波,else中有if』的狀況。什麼?想像不出來?明天回去公司開你自己的專案出來看看...

Robert C. Martin說,程式碼本身就要給予閱讀者足夠的資訊。所謂『足夠的資訊』包含很多,先前提過的命名是一種,這裡把條件分類提成帶語意的函式也是一種。於是我進一步分析,發現妹妹的條件其實可以概略分成四種:長得好看、物質生活高、工作表現好、個性好。於是我重新整理了一下,就像下面所述:

public boolean isOK(boolean isRich, int facePoint,
                        boolean hasHouse, boolean hasCar,
                        boolean isPhD, long income,
                        boolean isPlayBoy, boolean isFunny,
                        boolean hasHumor, boolean isGentle) {

        return isGoodLooking(facePoint) &&
                isGoodMaterialLife(isRich, hasHouse, hasCar) &&
                isGoodWork(isPhD, income) &&
                isGoodMind(isPlayBoy, isFunny, hasHumor, isGentle);

    }

    private boolean isGoodLooking(int facePoint) {
        return 90 < facePoint;
    }

    private boolean isGoodMaterialLife(boolean isRich, boolean hasHouse, boolean hasCar) {
        return isRich && hasHouse && hasCar;
    }

    private boolean isGoodWork(boolean isPhD, long income) {
        return isPhD && 3000000 < income;
    }

    private boolean isGoodMind(boolean isPlayboy, boolean isFunny, boolean hasHumor, boolean isGentle) {
        return !isPlayboy && isFunny && hasHumor && isGentle;
    }

您會不會有一種感覺:『這麼一來把原本很短的的程式拉得很長,哪有好讀?』好讀多了!別忘記,我們先前說的,這是波動拳中最簡單的一種喔!如果你的波動拳是複合型的,那麼這樣的拆解並給予語意,就是很好的投資了。

另外,這樣把條件拆出來並給予語意,增加可讀性其實不是最大好處喔!增加擴充性才是最大的好處。試想,萬一今天我不是只有一個妹妹,我有很多親戚朋友都來找我介紹對象,並且大家的條件都不一樣時怎麼辦?難道你要用『co過去改一改』大法,創作出一個又一個的波動拳?別鬧了,好嗎?

抽了邏輯後,你可以使用『pattern』設計模式,搭配靜態工廠與抽象介面,他們才是立馬將你從無限copy-paste地獄中解救出來的救世主!不喜歡的話,『decorator』設計模式也是不錯的選擇。方法有很多,你可以自由搭配,但是可以確定的是,不先把邏輯抽象化,要套用好的設計模式難度會很高。


『珍惜生命,遠離波動拳』不是一句口號。要寫出能跑不會錯的程式,對職業的工程師來說太簡單了。然而,產品中長期下來最大的成本不是開發,而是維護與修改。因此,寫出好維護、好懂的程式,才是平庸工程師進階到優秀工程師的最重要轉捩點。


上一篇
『我覺得自己來比較保險,我超有經驗』 -- 自動化部署的謬誤
下一篇
『逃不了就面對,打不贏就加入』 -- 論持續集成交付與自動化
系列文
再戰軟體工程30

尚未有邦友留言

立即登入留言