淺入深出Vue:程式碼整潔之封裝

若羽。發表於2019-07-18

深入淺出vue系列文章已經更新過半了,在入門篇中我們實踐了一個小小的專案。

《程式碼整潔之道》一書中提到過一句話:

  • 神在細節中

這句話來自20世紀中期註明現代建築大師 路德維希·密斯·範·德·羅所說,他秉承的是少即是多的建築設計哲學,玻璃幕牆等現代建築結構便是由他締造的。

而這句話也對軟體開發領域產生了不小的影響,同時在軟體開發領域中,很多概念都是源於其它行業,經典的便有現在所提到的建築學。

在實際開發中,當然也是需要注意細節的。很多人可能都碰到過 “維護不下去” 的程式碼,或者是 “無從下手”的程式碼,那麼這些程式碼是如何產生,以及是如何逐漸成長為“這麼不受待見”的程式碼呢?

碰巧,在入門篇的專案中同樣存在著這些問題,那麼讓我們在提高篇中逐一找出並解決這些問題!

封裝是什麼

封裝,就是整理

這是生活之中逃不開的一個詞。房間亂了,我們需要整理。那麼專案中的程式碼亂了,我們是否需要整理呢?

當然需要整理,但是這個整理是需要有合適的方式方法。

《程式碼整潔之道》開篇的序中,最開始便提出了整理一詞:

  • 整理即組織,是為了搞清楚事物所在,而通過恰當地命名之類的手段至關重要。

以上是書中原文,個人的理解是:

  • 整理,就是詞要達意,文要對題。

這麼解釋有點片面與抽象,但是可以由點入面,先吃透淺表面所透露出來的意思,再去深究其意。
這也是若羽系列文章為何取名為淺入深出的原因。如今的社會過於浮躁,大家都喜歡由繁入簡,而若羽偏要反其道而行之!

可以降低門檻為何要抬高門檻,知識只有在發生碰撞時才能發生質變和昇華,閉門造車的反例已經在歷史的滾滾長河中消失的無影無蹤。

如何封裝

首先我們來定義一個簡單的規則,符合這些規則,我們就應當考慮是否要封裝它們:

  • 一段程式碼包含著一定的業務邏輯。

回過頭來看看入門篇中文章列表頁面的程式碼:

<script>
    import axios from 'axios'
    export default {
        name: "List",
        data() {
            return {
                list: [],
            }
        },
        mounted() {
            this.init()
        },
        methods: {
            init() {
                axios.get('https://451ece6c-f618-436b-b4a2-517c6b2da400.mock.pstmn.io/list')
                    .then(res => {
                        this.list = res.data.Data
                    })
            }
        }
    }
</script>

這裡的 init函式,當這個元件例項被掛載時會被觸發。而裡面的邏輯是:

  • 向介面發起請求然後將返回值賦給當前元件作用域中的 list 變數

這個地方本身就是一個函式,為什麼還需要封裝呢?

這裡我們暫時只關注一下 init 函式中的程式碼,這裡其實包含了兩部分邏輯:

  1. 發起 ajax 請求

  2. 請求完成後將返回的資料賦值給元件內的變數

上面我們提到的整理一詞,為什麼要整理呢?因為混亂!我們才會要整理。如果本身就整整齊齊的,那我們為什麼需要去整理它呢。

這一段程式碼中包含了兩部分邏輯,它已經有點混亂了,因此我們需要整理它!

關於為什麼將其分析為 兩部分這一點若羽會在接下來的博文中單獨一篇來進行講解。

那麼這裡我們如何對其進行封裝呢,最簡單的辦法就是將發起請求的部分封裝起來,讓 init 函式看不見它,並不知道它幹了什麼事情。

這裡我們在 src 目錄下新建一個 test.js 檔案:

import axios from 'axios';

class Test {
    static test() {
        return axios.get('https://451ece6c-f618-436b-b4a2-517c6b2da400.mock.pstmn.io/list');
    }
}

export default Test;

都 9021 年了,我們當然要用上最最最新的語法啊!(就是習慣寫後端了唄)

這裡我們定義了一個 Test 的類,並且將請求的程式碼封裝到了一個靜態函式裡。
然後讓我們繼續重構一下 List.vue中的程式碼:

<script>
    import Test from '@/test'
    export default {
        name: "List",
        data() {
            return {
                list: [],
            }
        },
        mounted() {
            this.init()
        },
        methods: {
            init() {
                Test.test()
                    .then(res => {
                        this.list = res.data.Data
                    })
            }
        }
    }
</script>

此時有沒有覺得變得清爽一點呢?很好,清爽了就說明我們的目的達到了一半。

剩下一半就是不爽了~

命名:不耍流氓的封裝

在前面,我們封裝了 ajax 請求這一部分,但是我們卻耍了流氓!!!

只封裝了,但是沒有讓它 詞對其意,文對其題。一眼看過去,三個四個大大小小的 test 是什麼情況?

只看這段程式碼的話,完全看不懂這是啥意思呢!

這種行為就像是打掃房間的時候,垃圾掃好掃好,然後聚集在門口就這麼任由它放著!

距離我們成功重構這一小塊就差這臨門一腳了。

命名的標準很簡單,但也很難完全做到:

  • 詞對其意,文對其題,碼對其邏輯

那麼這裡我們是用來傳送 ajax 請求的,這該怎麼起名字?對於這個問題,一百個人裡面大概有好多個答案,這裡若羽的習慣是對其行為進行命名。因此這裡若羽的命名是:

  • RequestSender , 請求傳送者

函式的命名:

  • GetBlogList,獲取博文列表

讓我們來完成這臨門一腳:

test.js 重新命名為 RequestSender.js,程式碼:

import axios from 'axios';

class RequestSender {
    static GetBlogList() {
        return axios.get('https://451ece6c-f618-436b-b4a2-517c6b2da400.mock.pstmn.io/list');
    }
}

export default RequestSender;

這裡小小的表揚一下 Jetbrains 系列的工具,在 WebStorm 中先點選類名,然後按下 shift + f6 即可享受重新命名功能:同時修改檔名及檔案中引用的地方。

接下來繼續重構一下 List.vue 檔案:

<script>
    import RequestSender from '@/RequestSender'
    export default {
        name: "List",
        data() {
            return {
                list: [],
            }
        },
        mounted() {
            this.init()
        },
        methods: {
            init() {
                RequestSender.GetBlogList()
                    .then(res => {
                        this.list = res.data.Data
                    })
            }
        }
    }
</script>

完美~ 現在我們的程式碼表義性是不是變得更強了呢?
這就是封裝的魅力,細小之處見真章。

程式碼已經上傳至Gitee。Github晚點上傳,若羽這裡梯子最近有點問題,Gitee也方便大家直接訪問。

提示:可以看看若羽的提交,每一次的提交就對應了文章中的每一個重構步驟。

Gitee地址:https://gitee.com/Exceptation/qianrushenchuvue

覺得合胃口可以順手點個Star~

相關文章