設計模式在vue中的應用(一)

hailx發表於2019-01-14

前言

目錄整理:
設計模式在vue中的應用(一)
設計模式在vue中的應用(二)
設計模式在vue中的應用(三)
設計模式在vue中的應用(四)
設計模式在vue中的應用(五)
設計模式在vue中的應用(六)
設計模式在vue中的應用(七)

為什麼要寫這些文章呢。正如設計模式(Design Pattern)是一套被反覆使用、多數人知曉的、經過分類的、程式碼設計經驗的總結(來自百度百科)一樣,也是想通過分享一些工作中的積累與大家探討設計模式的魅力所在。
在這個系列文章中為了輔助說明引入的應用場景都是工作中真實的應用場景,當然無法覆蓋全面,但以此類推也覆蓋到了常見的業務場景



最近需要維護一個老專案,裡面有個需求如下:
有一個頁面要根據路由引數type分別渲染三個表單,三個表單中有相同的輸入項也有不同的輸入項其中某些輸入項又會有一個對應的xstatus來判斷需不需顯示。

一,需求

需求很簡單就如文章開篇,公司專案暫時不方便貼出來,只好強行意淫一個場景幫助理解。

假設:我現在要將登陸、手機註冊、郵箱註冊通過一個路由用引數type標識渲染那個表單;登陸過程中如果賬號密碼輸入錯誤次數超過3次就需要輸入影像驗證碼,通過codeStatus進行標識。

二,程式碼

當我們接手維護一個老專案時遇到各種問題總是會抱怨別人家的程式碼,好,我們先來看一下別人家的程式碼

設計模式在vue中的應用(一)
這種程式碼實現想必大家都身經百戰了,就不貼詳細實現了。邏輯很簡單,按需求每個form根據type做if判斷,然後input根據status做if操作。

我接手的老專案需求要比這個複雜的多,內部實現就是這麼搞的,僅template就近500多行。我要處理的需求很簡單——修改其中一個input對應的欄位名,看著這個檔案我是萬臉懵逼,關鍵是提測後沒有通過,由於對這個檔案處理的業務邏輯不熟,需要修改的這個input在兩個表單裡面分別由兩個不同的status來判斷顯示狀態,而我只改了一個地方的

吐槽誰都會,吐槽完了就得優化這塊邏輯了

三,優化一

無腦操作:

既然有三個表單我們就封裝三個form元件,每個元件負責自己的渲染邏輯

設計模式在vue中的應用(一)
為什麼說是無腦操作呢,寫過vue的coder這種方式已經深入我們的血脈了,哈哈哈哈哈。
看下效果怎麼樣——

假設專案原本採用這種方式組織程式碼,我要去完成改input欄位名的需求,我還是可能只改了register-mobile遺漏掉register-email,最終結果提測不通過,有bug了

老實說這種方式只是將500+行程式碼分成了三個檔案而已,至於優化還談不上,說程式碼美化還差不多

四,優化二

設計模式登場,先看程式碼
目錄結構:

設計模式在vue中的應用(一)
檔案Login.vue
設計模式在vue中的應用(一)
檔案RegisterMobile.vue
設計模式在vue中的應用(一)
檔案./input/ImgCode.vue
設計模式在vue中的應用(一)
怎麼做的呢,我們在優化一的基礎上將每個input也元件化了,每個input元件接受typestatus兩個屬性,form以元件的形式使用input,這樣我們對input的修改會自動更新到所有引用了的form,input是否顯示的邏輯在input元件內部有自己控制
看下效果怎麼樣——

假設專案採用這種程式碼組織方式,我要去完成改input欄位名的需求。找到對應的input元件,完全不用關心對typestatus的判斷邏輯,只需修改欄位名。因為兩個form使用了同一個input,自測register-mobile沒問題,那麼register-email同樣不會有問題,就算業務不熟悉,也不會出現前面尷尬的狀況——bug。提交測試。轉身就下樓喝咖啡,就是這麼自信。

效果好像很贊。這節開頭就提到了設計模式,那到底用到了什麼設計模式呢。先來點理論知識:

外觀模式:為子系統中的一組介面提供一個一致的介面,Facade模式定義了一個高層介面,這個介面使得這一子系統更加容易使用。引入外觀角色之後,使用者只需要直接與外觀角色互動,使用者與子系統之間的複雜關係由外觀角色來實現,從而降低了系統的耦合度

LoginRegisterMobileRegisterEmail定義了三個外觀角色,每個input元件作為子系統。外觀角色只關心使用那些子系統,子系統對status的邏輯在子系統內部處理,這樣就降低了系統的耦合度

五,優化三

取名字終究是一件比較傷腦的事,根據上面的實現我們需要三個form元件LoginRegisterMobileRegisterEmail這一下要取三個名字,頭疼!!!
就不能一個元件Form.vue嗎

設計模式在vue中的應用(一)
將所有的input元件註冊到form元件上,因為input元件內部有通過typestatus來判斷自己需不需要顯示,我們的需求同樣達到了
看下效果怎麼樣——

將原本的三個元件簡化成一個元件,在這個點上確實達到了優化的效果。但是有一個缺點,當業務邏輯很複雜順著這個規則寫下去,可能在form元件裡面註冊非常多的input元件,如果我們想知道那些input元件會在手機註冊時用到,單從form元件是無法判別的,需要從這些input元件的內部邏輯一個一個看下去,才能得到我們想要的結果,不得不說這個過程是痛苦的。

六,優化四

優化三的問題是在某個給定的type下例項化了很多無用input,雖然它們有內部邏輯判斷不會顯示。如果我們要什麼元件就給我們那個元件就好了。

我想要iphoneX,大佬能造一個嗎?大佬:好
我想要mete20,大佬能造一個嗎?大佬:好
我想要小米,大佬能造一個嗎?大佬:好
複製程式碼

大佬這麼牛逼,大佬是誰呀?答:富士康——手機工廠

工廠模式

首先造一個input factory,專門用來生成input:

設計模式在vue中的應用(一)

啟用工廠生產:

設計模式在vue中的應用(一)

七、結尾

為了完成文章開篇這個小需求,我們使用了設計模式中的外觀模式、工廠模式。相比於系統原本的實現方式,優化後的方案系統解耦程度更高,可維護性更強。


本文實現同樣適用於react,為什麼文章以vue做題?vue的template讓我們在理解一些概念的時候可能會有點不適應,而react的jsx可以看做就是在寫JavaScript對各種概念實現更靈活
友情提示:設計模式在vue中的應用應該會寫一個系列,喜歡的同學記得關注下

相關文章