代碼重構

這是一個持續跟新的文章。

這篇文章會記錄下我對代碼重構的思考和讀書的總結。

1.提煉函數

  • 在JavaScript開發中,我們大部分時間都在與函數打交道,所以我們希望這些函數有良好的命名,函數體內包含的邏輯清晰明瞭。
  • 如果一個函數過長,不得不加上若干註釋才能讓這個函數顯得易讀一些,那這些函數就很有必要進行重構。
  • 如果在函數中有一段代碼可以被獨立出來,那我們最好把這些代碼放進另外一個獨立的函數中,好處有如下幾點。
    • 避免出現超大函數。
    • 獨立出來的函數有助於代碼複用。
    • 獨立出來的函數更容易被覆寫。
    • 獨立出來的函數如果有一個良好的命名,它本身就起到了註釋的作用。
        var getUserInfo = function () {
            ajax('http:// xxx.com/userInfo', function (data) {
                console.log('userId:' + data.userId);
                console.log('userName:' + data.userName);
                console.log('nickName:' + data.nickName);
            });
        };

        改成:
        var getUserInfo = function () {
            ajax('http:// xxx.com/userInfo', function (data) {
                printDetails(data);
            });
        };

        var printDetails = function (data) {
            console.log('userId:' + data.userId);
                console.log('userName:' + data.userName);
                console.log('nickName:' + data.nickName);
        }

2.合併重複的條件片段

        var paging = function (currPage) {
            if(currPage <= 0){
                currPage = 0;
                jump(currPage); //跳轉
            }else if(currPage >= totalPage){
                currPage = totalPage;
                jump(currPage); //跳轉
            }else{
                jump(currPage); //跳轉
            }
        };
    可以看到,負責跳轉的代碼jump(currPage)在每個條件分支內都出現了,所以完全可以把這句代碼獨立出來。
        var paging = function (currPage) {
            if(currPage <= 0){
                currPage = 0;
            }else if(currPage >= totalPage){
                currPage = totalPage;
            }
            jump(currPage); //跳轉
        };

3.把條件分支語句提煉成函數

        var getPrice = function (price) {
            var date = new Date();
            if(date.getMonth() >= 6 && date.getMonth() <= 9){ //夏天
                return price * 0.8;
            }
            return price;
        }

        上面的代碼表達的意圖和代碼自身還存在一些距離,閱讀代碼的人必須要多花一些精力才能明白它傳達的意圖。
        其實可以把這句代碼提煉成一個單獨的函數,技能更準確地表達代碼的意思,函數名本身又能起到註釋的作用。
        代碼如下

        var isSummer = function () {
            var date = new Date();
            return date.getMonth() >= 6 && date.getMonth() <= 9;
        }

        var getPrice = function (price) {
            if(isSummer()){ //夏天
                return price * 0.8;
            }
            return price;
        };

4.提前讓函數退出代替嵌套條件分支

許多程序員都有這樣一個觀念:“每個函數只能有一個入口和一個出口。”現代編程語言都會限制函數只有一個入口。但關於“函數只有一個出口”,往往會有一些不同的看法。
下面這段僞代碼是遵守“函數只有一個出口”的典型代碼:
    var del = function (obj) {
            var ret;
            if(!obg.isReadOnly) { //不爲只讀才能刪除
                if(obj.isFolder) { //如果是文件夾
                    ret = deleteFolder(obj);
                }else if (obj.isFile){
                    ret = deleteFile(obj);
                }
            }
            return ret;
        }
        用《重構》中的話說,嵌套的條件分支往往是由一些深信“每個函數只能有一個出口的”程序員寫出的。
        但實際上,如果對函數的剩餘部分不感興趣,那就應該立即退出。
        引導閱讀者去看一些沒有用的else片段,只會妨礙他們對程序的理解。
        var del = function (obj) {
            if(obj.isReadOnly){ //反轉if表達式
                return;
            }
            if(obj.isFolder){
                return deleteFolder(obj);
            }
            if(obj.isFile){
                return deleteFile(obj);
            }
        }
發佈了44 篇原創文章 · 獲贊 9 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章