當前位置:
首頁 > 最新 > 重構-設計API的擴展機制

重構-設計API的擴展機制

1.前言

上篇文章,主要介紹了重構的一些概念和一些簡單的實例。這一次,詳細的說下項目中的一個重構場景--給API設計擴展機制。目的就是為了方便以後能靈活應對需求的改變。當然了,是否需要設計擴展性這個要看API的需求。如果大家有什麼建議,歡迎評論留言。


2.擴展性表現形式

2-1.prototype

這個可以說是JS裡面最原的一個擴展。比如原生JS沒有提供打亂數組順序的API,但是開發者又想方便使用,這樣的話,就只能擴展數組的prototype。代碼如下

運行結果

功能是實現了。但是上面的代碼,只想借用例子講解擴展性,大家看下就好。不要模仿,也不要在項目這樣寫。現在基本都禁止這樣開發了。理由也很簡單,之前的文章也有提到過。這裡重複一下。

這樣就污染了原生對象Array,別人創建的Array也會被污染,造成不必要的開銷。最可怕的是,萬一自己命名的跟原生的方法重名了,就被覆蓋原來的方法了。

2-2.jQuery

關於 jQuery 的擴展性,分別提供了三個API:$.extend()、$.fn和$.fn.extend()。分別對jQuery的本身,靜態方法,原型對象進行擴展,基於jQuery寫插件的時候,最離不開的應該就是$.fn.extend()。

參考鏈接:

理解jquery的$.extend()、$.fn和$.fn.extend()

Jquery自定義插件之$.extend()、$.fn和$.fn.extend()

2-3.VUE

對VUE進行擴展,引用官網(插件)的說法,擴展的方式一般有以下幾種:

1.添加全局方法或者屬性,如: vue-custom-element

2.添加全局資源:指令/過濾器/過渡等,如 vue-touch

3.通過全局 mixin 方法添加一些組件選項,如: vue-router

4.添加 Vue 實例方法,通過把它們添加到 Vue.prototype 上實現。

5.一個庫,提供自己的 API,同時提供上面提到的一個或多個功能,如 vue-router

基於VUE的擴展。在組件,插件的內容提供一個install方法。如下

使用組件

上面幾個擴展性的實例分別是原生對象,庫,框架的擴展,大家可能覺得有點誇誇而談,那下面就分享一個日常開發常用的一個實例。


看了上面那些擴展性的實例,下面看下一個在日常開發使用得也很多的一個實例:表單驗證。這塊可以說很簡單,但是做好,做通用不簡單。看了《JavaScript設計模式與開發實踐》,用策略模式對以前的表單驗證函數進行了一個重構。下面進行一個簡單的分析。

下面的內容,代碼會偏多,雖然代碼不難,但還是強烈建議大家不要只看,要邊看,邊寫,邊調試,不然作為讀者,很可能不知道我的代碼是什麼意思,很容易懵。下面的代碼回涉兩個知識:開放-封閉原則和策略模式,大家可以自行了解。

3-1.原來方案

函數調用方式

3-2.存在問題

這樣方法,相信大家看的也難受,因為問題確實是比較多。

1.一個欄位進入,可能要經過三種判斷(空值,規則,長度)。如果只是一個簡單的電話號碼規則校驗,就要經過其他兩種沒必要的校驗,造成不必要的開銷。運行的流程就如同下面。

2.規則校驗裡面,只有這幾種校驗,如果要增加其他校驗,比如增加一個日期的規則,無法完成。如果一直修改源碼,可能會導致函數巨大。

3.寫法不優雅,調用也不方便。

3-3.代替方案

針對上面2-2的三個問題,逐個進行改善。

因為調用方式就不方便,很難在不改變validateForm調用方式的同時,優化重構內部的代碼,又增加擴展性。重寫這個方法又不可能,因為有個別的地方已經使用了這個API,自己一個一個的改不現實,所以就不修改這個validateForm,新建一個新的API:validate。在以後的項目上,也盡量引導同事放棄validateForm,使用新的API。

上面第一個,優化校驗規則,每次校驗(比如空值,長度,規則),都是一個簡單的校驗,不再執行其他沒必要的校驗。運行流程如同下面。

如果又有其它的規則,又得改這個,這樣就違反了開放-封閉原則。如果多人共用這個函數,規則可能會很多,ruleData會變的巨大,造成不必要的開銷。比如A頁面有金額的校驗,但是只有A頁面有。如果按照上面的方式改,在B頁面也會載入金額的校驗規則,但是根本不會用上,造成資源浪費。

所以下面應用開放-封閉原則。給函數的校驗規則增加擴展性。在實操之前,大家應該會懵,因為一個函數,可以進行校驗的操作,又有增加校驗規則的操作。一個函數做兩件事,就違反了單一原則。到時候也難維護,所以推薦的做法就是分介面做。如下寫法。

如上代碼所示,這裡需要往ruleData添加日期範圍的校驗,這裡可以添加。但是不能訪問和修改ruleData的東西,有一個保護的作用。還有一個就是,比如在A頁面添加日期的校驗,只在A頁面存在,不會影響其它頁面。如果日期的校驗在其它地方都可能用上,就可以考慮,在全局裡面為ruleData添加日期的校驗的規則。

至於第三個問題,這樣的想法,可能不算太優雅,調用也不是太方便,但是就我現在能想到的,這個就是最好方案啊了。

這個看似是已經做完了,但是大家可能覺得有一種情況沒能應對,比如下面這種,做不到。

因為上面的check介面,只要有一個錯誤了,就立馬跳出了,不會校驗下一個。如果要實現下面的功能,就得實現,如果有一個值校驗錯誤,就記錄錯誤信息,繼續校驗下一個,等到所有的校驗都執行完了之後,如下面的流程圖。

代碼上面(大家先忽略alias這個屬性)

看到結果,現在所有的不合法的數據的記錄都返回回來了。至於當時alias現在揭曉用處。

比如頁面是vue渲染的,根據alias可以這樣處理。

如果是jQuery渲染的,根據alias可以這樣處理。

3-4.向下兼容方案

因為項目之前有使用了以前的校驗API,不能一道切,在以前的API沒廢棄之前,不能影響之前的使用。所以要重寫以前的validateForm,使之兼容現在的新API:validate。


今天的例子就到這裡了,這個例子,無非就是給API增加擴展性。這個例子比較簡單,不算難。大家用這個代碼在瀏覽器上運行,就很好理解。如果大家對這個例子有什麼更好的建議,或者代碼上有什麼問題,歡迎在評論區留言,大家多交流,相互學習。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 守候書閣 的精彩文章:

TAG:守候書閣 |