一本一道久久a久久精品综合蜜臀,亚洲日韩激情一区二区,国产国产东北刺激毛片对白,国产精品三级一区二区,91久久精品日日躁夜夜躁欧美
您當前的位置主頁 > 網(wǎng)站推廣 > 瀏覽文章

復(fù)雜表單應(yīng)用解耦 淘寶機票訂單實踐

來源:網(wǎng)站推廣 2012-11-14

快速提升網(wǎng)站銷量,使用365webcall網(wǎng)頁客服工具

背景

在web應(yīng)用中,復(fù)雜表單這類web應(yīng)用富交互元素多,業(yè)務(wù)邏輯復(fù)雜,犬牙交錯,且需求變化頻繁。及容易成為晦澀和幽暗之地,也經(jīng)常是各種代碼壞味道的來源。針對這種典型的復(fù)雜應(yīng)用,本文以淘寶機票訂單為例提出一種架構(gòu)模式梳理和消化表單帶來的復(fù)雜性。

模塊和組件劃分

解決復(fù)雜表單的的第一步,劃分模塊。

概念上,為了復(fù)用和解耦方便,應(yīng)將模塊按照功能的內(nèi)聚程度進行劃分。強相關(guān),頻繁溝通和交互的功能應(yīng)該歸為一個模塊。模塊間盡量不存在依賴關(guān)系。也就是常說的“高內(nèi)聚,低耦合”。

如下圖所示,淘寶機票訂單頁面主要有被分為7個主要模塊。

模塊劃分完畢,下一步確認組成模塊的組件。

關(guān)于模塊和組件的區(qū)分。一般按照以下三個緯度考量。

是否有業(yè)務(wù)邏輯參與。

是否包含html。

是否具備一定獨立性。

“模塊”,定義為一個包含”html”、”css(圖片被認為是css的一部分)“、”javascript”的代碼集。模塊的應(yīng)用方式多為通過web模板技術(shù)(如:velocity、freemarker、php)。因為包含了html,使得模塊必須通過服務(wù)端合并加載并且最終推送到用戶瀏覽器。此外,“模塊”還是具備一定獨立業(yè)務(wù)和交互的集合,最好可以被其他頁面引用。良好的獨立性也可以幫助協(xié)同開發(fā),在實際開發(fā)中可多人可以并行開發(fā)多個獨立模塊,提高效率。

“組件”,定義為一個僅包含”css”和”javascript”的代碼集。正因為不包含html,所以組件可通過javascript異步加載。因為這種可異步加載的特性,組件在復(fù)用方面的容易性遠超模塊。組件沒有業(yè)務(wù)邏輯或者僅有少部分公共業(yè)務(wù)邏輯。業(yè)務(wù)邏輯越多,組件的可復(fù)用性就越低。

模塊、組件間通訊

組件/模塊劃分的目的是將彼此間相對獨立的功能分離,前面通過模塊和組件的劃分解決了分離問題。實際中,模塊之間存在協(xié)作關(guān)系。模塊間應(yīng)以一種輕量的方式協(xié)作。一般的為了更好的分離和解耦,可以考慮用廣播的方式在模塊間溝通,考慮使用事件的方式在組件間通訊。

如下圖所示,淘寶機票訂單頁面的數(shù)據(jù)流向。

不同模塊在后期均有可能擴展小功能。例如不定期的活動優(yōu)惠等。事件廣播可以讓不同模塊/組件間新增功能影響面縮小。在淘寶機票訂單中應(yīng)用中,使用廣播組件通訊主要用來完成以下意圖。

1、知會。

知會的特性在于異步通訊。廣播發(fā)起方只需要放出事件,無需等待其他關(guān)注者完成處理。稱為異步廣播。例如表單模塊的內(nèi)容變更需要知會到顯示訂單金額的模塊,顯示訂單金額的模塊接受事件后需要更改金額。

基于這種方式的通訊,各模塊之需要做好自己的事情,外部關(guān)注的時間廣播出去即可。異步廣播還有一個好處是系統(tǒng)堅固性比較強,廣播發(fā)送者不會因為時間監(jiān)聽者的使用不當而異常。

2、請求數(shù)據(jù)

例如,模塊6(負責(zé)提交)需要在被點擊后從模塊2(乘機人表單),模塊4(聯(lián)系地址)、模塊7(金額計算)。獲取具體數(shù)據(jù)提交。請求數(shù)據(jù)的場景特性在于,廣播發(fā)起者需要等待時間處理者完成處理后再繼續(xù)下一步行為。稱為同步廣播。同步廣播的應(yīng)用有些費解。代碼說明原理和應(yīng)用。

基于此機制。提交模塊只需要負責(zé)綜合校驗,浮層,網(wǎng)絡(luò)請求及異常處理。而具體請求的內(nèi)容由其他模塊決定。對后續(xù)模塊的擴充起到了很好的左右。

復(fù)雜組件拆分

模塊和組件劃分完畢后,可能會發(fā)現(xiàn)某些組件非常復(fù)雜,幾乎占據(jù)了整個web應(yīng)用一半以上的代碼。這部分組件由純js實現(xiàn),并且使用javascript模塊加載器加載。

同一個組件大量代碼糾結(jié)在一起,最終還是會導(dǎo)致架構(gòu)腐化。因此,復(fù)雜組件需要進一步拆分。在淘寶機票訂單中,乘機人信息組件是一個復(fù)雜組件。如下圖所示:

拆分這類輸入型的復(fù)雜組件,一般來說有兩種思路方式。

縱切,組件樹型式。

將組件進一步劃分為更細力度的輸入組件,將每個輸入域作為一個單獨組件。最終形成一個組件樹。

這樣的組織方式結(jié)構(gòu)嚴謹層級清晰,最大的優(yōu)點是很容易支持字段擴展。

但考慮如下場景,為了盡量友好的提示用戶,需要在輸入域外的某處增加提示幫助。

這種場景下組件樹的組織方式每次在面對變化時就會略顯手忙腳亂。難道把每個地方出現(xiàn)的tip都座位獨立組件看待嗎?

字段級的適普性降低了適應(yīng)細節(jié)調(diào)整的能力,付出的代價在于界面體驗。

橫切,AOP式。

將所有輸入域抽象的看待為同一個組件。按照組件的富應(yīng)用特性分層看待。在本例中,乘機人組件被按照從簡單到復(fù)雜分為3個切面。

切面1-基礎(chǔ)展現(xiàn)層只負責(zé)最基礎(chǔ)的可完成輸入的表單控件,及基礎(chǔ)dom管理。

切面2-富展現(xiàn)層負責(zé)修飾base層的基礎(chǔ)html控件,形成富輸入控件。

切面3-校驗層負責(zé)對base層的輸入數(shù)據(jù)進行業(yè)務(wù)級校驗。

未來,如果新增tip或者其他業(yè)務(wù)邏輯,增加一個新切面即可,完全或者很少需要修改老代碼文件。

淘寶機票訂單采用了AOP這種方式,從最終代碼量上來看,可以看出復(fù)雜度被比較均衡的分布到不同文件中去。

同樣,這種方式也有局限,如果需要擴展字段,那將是一個災(zāi)難,你有可能需要到每一個切面里面去做修改。

有句老話說的好,沒有最優(yōu)方案,只有最適合的解決方案,任何解決方案,都需要放到具體場景中去評判。事實上,對這個問題的進一步研究,可以發(fā)現(xiàn)以下規(guī)律。

對于一個組件、模塊,同時追求簡單設(shè)計、適普性(字段級擴充)、界面體驗是不可能的。如果場景需要適應(yīng)字段靈活擴展,那就采用縱切的模式。如果使用場景需字段確定,需要更多細節(jié)控制力度,那就橫切,AOP式。如果兩者都要兼顧,就需要引入復(fù)雜設(shè)計,綜合運用橫切和縱切。但是這樣形成的最終設(shè)計會很復(fù)雜,開發(fā)和可維護性上會有代價付出。

對于淘寶機票這類互聯(lián)網(wǎng)應(yīng)用,使用了橫切的方式來拆分組件,因為在這個場景中,字段的數(shù)量是相對固定的,而圍繞固定數(shù)量字段的優(yōu)化需求是層出不窮的。然而在企業(yè)內(nèi)網(wǎng)應(yīng)用或者網(wǎng)站后臺web應(yīng)用中,字段的變化會比較頻繁。建議主要采用縱切的思路劃分。

表單校驗

有表單的地方就有校驗。項目初期,校驗的功能總是不起眼。等待項目后期時候經(jīng)常會發(fā)現(xiàn)校驗已經(jīng)占據(jù)了巨大工作量并且成為海量bug的源頭。因此校驗是一種典型的容易被輕視單又蘊含巨大工作量的事情,需要特別對待,專門設(shè)計。

一般來說,這根據(jù)校驗根據(jù)其復(fù)雜度可以分為以下兩類:

格式校驗

格式校驗一般是校驗用戶輸入的格式是否滿足要求,比如是否數(shù)字、電話號碼、郵箱等等。此類校驗的特點是校驗域單一,一般只對一個input或者某個組件的value進行檢查。格式類校驗應(yīng)與與用戶展現(xiàn)非常接近,一種非常好的做法是將此類校驗信息直接描述在html標簽屬性中。html5中input的pattern屬性就是一種基于這種思想的解決方案。

邏輯校驗

邏輯校驗是滿足格式校驗后,繼續(xù)進行的與業(yè)務(wù)相關(guān)的校驗,例如是否存在相同用戶名,輸入的生日是否和身份證號不符等等。此類校驗的一般涉及多個輸入域,要綜合處用戶的輸入內(nèi)容一起校驗。此類校驗邏輯復(fù)雜,不適合寫在html中。

目前有很多流行的form校驗框架解決校驗問題,如何引入合適的校驗框架,先從理解校驗這件事的過程開始。

典型的一個校驗過程如下,用戶在某個input處完成輸入,應(yīng)用在某個時刻被觸發(fā)校驗,可以是失去焦點或者keyup或者其他。被觸發(fā)的校驗過程找到此處input所需要的校驗規(guī)則(有時候這個規(guī)則被直接寫在html中)判單正確與否,如果正確,可能有提示,如果錯誤,可能也有提示。

從以上場景的描述中,可以找到校驗的幾個關(guān)鍵環(huán)節(jié)。這里局部采用一下管理學(xué)上經(jīng)典的5w1h問題分析方法來分析問題

who: 哪個輸入控件的內(nèi)容需要校驗。這是框架是解決不了的。要對哪個輸入域做校驗應(yīng)該是應(yīng)用傳遞進入的。

when: 何時被觸發(fā)校驗。比如說是“who”失去焦點時。變化太多,框架解決不了。只能被動觸發(fā)。

what: 做什么校驗。有時候這個”what”被寫在html中;旧,所有格式校驗都是固定的,這個問題應(yīng)框架解決。但框架應(yīng)預(yù)留接口做更加復(fù)雜的業(yè)務(wù)校驗。

how: 校驗完畢后的動作?蚣懿荒軟Q定做什么,但是在校驗結(jié)果出來后,框架應(yīng)能知會到外部調(diào)用者。

在設(shè)計框架或者選擇已有框架時,首先要區(qū)分框架的邊界,簡單來說,就是做什么和不做什么。框架應(yīng)實現(xiàn)相對固定的業(yè)務(wù)流程。同時對可變部分預(yù)留足夠的靈活性。

一個通用的校驗框架一定是不含界面部分的。界面是多變和難以窮舉的,是用tip顯示錯誤,還是在輸入域附近顯示,是否需要動畫,是否需要修改輸入域的視覺狀態(tài),這些可變化的部分應(yīng)為框架外部內(nèi)容,由更專業(yè)的tip組件或者popup來完成?蚣苤粦(yīng)該負責(zé)在校驗完成時候知會相關(guān)組件完成顯示錯誤提示等若干事情。

基于以上的分析,校驗框架應(yīng)該具備以下規(guī)格

1. 解決what問題。內(nèi)置了各種格式校驗規(guī)則,如電話號碼、e-mail等.并且能夠靈活定義新的邏輯校驗。

2. 解決who問題。說明如何根據(jù)輸入的字符真正找到who對應(yīng)的value。并且能夠?qū)τ谶@個who使用哪些校驗規(guī)則

3. 解決when問題。提供一個觸發(fā)校驗的方法。

4. 解決how問題。產(chǎn)生校驗結(jié)果后能夠知會外部的功能框架。

在淘寶機票訂單應(yīng)用中,依據(jù)上述原則自行設(shè)計了一個Validator框架,接口定義如下,Validator是校驗框架對象。

在構(gòu)造函數(shù)中提供表格化的校驗邏輯定義型式。如下圖所示,傳遞如下結(jié)構(gòu),定義每個字段對應(yīng)的校驗方式。在下圖中,定義每行為一個field,每個field有若干rule,每個rule可以是框架內(nèi)置的格式校驗,也可以是自定義的邏輯校驗,實際上是函數(shù)名。

Validator框架提供validate()方法,validate方法有兩個行為,如果不指定參數(shù),將依次執(zhí)行完所有field的校驗,并且將最終結(jié)果返回。如果執(zhí)行一個field name,框架將只校驗field name對應(yīng)的輸入域。

一旦執(zhí)行validate()方法,無論校驗結(jié)果如何,框架均向其觀察者發(fā)送事件’onValidate’。以便觸發(fā)后續(xù)動作。

一些輔助參數(shù),需要提供一個從field name找到輸入域value的function。

總結(jié)

在處理復(fù)雜表單時,首先通過合理模塊、組件劃分,將復(fù)雜度分散。然后利用詳細和廣播機制解決分散的模塊和組件間通問題。接著,過于復(fù)雜的組件要考慮進一步拆分,具體拆分的方式有縱切和橫切兩種,根據(jù)具體使用場景決定。最后,不要小看了校驗,需要特別對待,專門設(shè)計。

文章編輯: 365webcall在線客服(www.365webcall.com)

我的評論

登錄賬號: 密碼: 快速注冊 | 找回密碼

一本一道久久a久久精品综合蜜臀,亚洲日韩激情一区二区,国产国产东北刺激毛片对白,国产精品三级一区二区,91久久精品日日躁夜夜躁欧美