複雜表單應用解耦,淘寶機票訂單實踐

2021-02-15 開發者
開發者(KaiFaX)
面向開發者、程式設計師的專業平臺!背景

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

模塊和組件劃分

解決複雜表單的的第一步,劃分模塊。

概念上,為了復用和解耦方便,應將模塊按照功能的內聚程度進行劃分。強相關,頻繁溝通和交互的功能應該歸為一個模塊。模塊間儘量不存在依賴關係。也就是常說的「高內聚,低耦合」。
如下圖所示,淘寶機票訂單頁面主要有被分為7個主要模塊。

模塊劃分完畢,下一步確認組成模塊的組件。
關於模塊和組件的區分。一般按照以下三個緯度考量。

是否有業務邏輯參與。

是否包含html。

是否具備一定獨立性。

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

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

模塊、組件間通訊

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

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

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

1、知會。
知會的特性在於異步通訊。廣播發起方只需要放出事件,無需等待其他關注者完成處理。稱為異步廣播。例如表單模塊的內容變更需要知會到顯示訂單金額的模塊,顯示訂單金額的模塊接受事件後需要更改金額。
基於這種方式的通訊,各模塊之需要做好自己的事情,外部關注的事件廣播出去即可。異步廣播還有一個好處是系統堅固性比較強,廣播發送者不會因為事件監聽者的使用不當而異常。

2、請求數據
例如,模塊6(負責提交)需要在被點擊後從模塊2(乘機人表單),模塊4(聯繫地址)、模塊7(金額計算)。獲取具體數據提交。請求數據的場景特性在於,廣播發起者需要等待事件處理者完成處理後再繼續下一步行為。稱為同步廣播。

基於此機制。提交模塊只需要負責綜合校驗,浮層,網絡請求及異常處理。而具體請求的內容由其他模塊決定。對後續模塊的擴充起到了很好的左右。

複雜組件拆分

模塊和組件劃分完畢後,可能會發現某些組件非常複雜,幾乎佔據了整個web應用一半以上的代碼。這部分組件由純js實現,並且使用javascript模塊加載器加載。
同一個組件大量代碼糾結在一起,最終還是會導致架構腐化。因此,複雜組件需要進一步拆分。在淘寶機票訂單中,乘機人信息組件是一個複雜組件。如下圖所示:

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

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

這樣的組織方式結構嚴謹層級清晰,最大的優點是很容易支持欄位擴展。
但考慮如下場景,為了儘量友好的提示用戶,需要在輸入域外的某處增加提示幫助。

這種場景下組件樹的組織方式每次在面對變化時就會略顯手忙腳亂。難道把每個地方出現的tip都座位獨立組件看待嗎?
欄位級的適普性降低了適應細節調整的能力,付出的代價在於界面體驗。

橫切,AOP式。
將所有輸入域抽象的看待為同一個組件。按照組件的富應用特性分層看待。在本例中,乘機人組件被按照從簡單到複雜分為3個切面。

切面1-基礎展現層只負責最基礎的可完成輸入的表單控制項,及基礎dom管理。
切面2-富展現層負責修飾base層的基礎html控制項,形成富輸入控制項。
切面3-校驗層負責對base層的輸入數據進行業務級校驗。
未來,如果新增tip或者其他業務邏輯,增加一個新切面即可,完全或者很少需要修改老代碼文件。

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

同樣,這種方式也有局限,如果需要擴展欄位,那將是一個災難,你有可能需要到每一個切面裡面去做修改。

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

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

對於淘寶機票這類網際網路應用,使用了橫切的方式來拆分組件,因為在這個場景中,欄位的數量是相對固定的,而圍繞固定數量欄位的優化需求是層出不窮的。然而在企業內網應用或者網站後臺web應用中,欄位的變化會比較頻繁。建議主要採用縱切的思路劃分。

表單校驗

有表單的地方就有校驗。項目初期,校驗的功能總是不起眼。等待項目後期時候經常會發現校驗已經佔據了巨大工作量並且成為海量bug的源頭。因此校驗是一種典型的容易被輕視單又蘊含巨大工作量的事情,需要特別對待,專門設計。

一般來說,這根據校驗根據其複雜度可以分為以下兩類:

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

邏輯校驗
邏輯校驗是滿足格式校驗後,繼續進行的與業務相關的校驗,例如是否存在相同用戶名,輸入的生日是否和身份證號不符等等。此類校驗的一般涉及多個輸入域,要綜合處用戶的輸入內容一起校驗。此類校驗邏輯複雜,不適合寫在html中。

目前有很多流行的form校驗框架解決校驗問題,如何引入合適的校驗框架,先從理解校驗這件事的過程開始。
典型的一個校驗過程如下,用戶在某個input處完成輸入,應用在某個時刻被觸發校驗,可以是失去焦點或者keyup或者其他。被觸發的校驗過程找到此處input所需要的校驗規則(有時候這個規則被直接寫在html中)判單正確與否,如果正確,可能有提示,如果錯誤,可能也有提示。
從以上場景的描述中,可以找到校驗的幾個關鍵環節。這裡局部採用一下管理學上經典的5w1h問題分析方法來分析問題

who: 哪個輸入控制項的內容需要校驗。這是框架是解決不了的。要對哪個輸入域做校驗應該是應用傳遞進入的。

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

what: 做什麼校驗。有時候這個」what」被寫在html中。基本上,所有格式校驗都是固定的,這個問題應框架解決。但框架應預留接口做更加複雜的業務校驗。

how: 校驗完畢後的動作。框架不能決定做什麼,但是在校驗結果出來後,框架應能知會到外部調用者。

在設計框架或者選擇已有框架時,首先要區分框架的邊界,簡單來說,就是做什麼和不做什麼。框架應實現相對固定的業務流程。同時對可變部分預留足夠的靈活性。

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

基於以上的分析,校驗框架應該具備以下規格
1. 解決what問題。內置了各種格式校驗規則,如電話號碼、e-mail等.並且能夠靈活定義新的邏輯校驗。
2. 解決who問題。說明如何根據輸入的字符真正找到who對應的value。並且能夠對於這個who使用哪些校驗規則
3. 解決when問題。提供一個觸發校驗的方法。
4. 解決how問題。產生校驗結果後能夠知會外部的功能框架。

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

在構造函數中提供表格化的校驗邏輯定義型式。如下圖所示,傳遞如下結構,定義每個欄位對應的校驗方式。在下圖中,定義每行為一個field,每個field有若干rule,每個rule可以是框架內置的格式校驗,也可以是自定義的邏輯校驗,實際上是函數名。

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

一旦執行validate()方法,無論校驗結果如何,框架均向其觀察者發送事件』onValidate』。以便觸發後續動作。

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

總結

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

來源:http://ued.taobao.org/blog/2012/11/refactor-complex-form/

1. 回復「m」可以查看歷史記錄;

2. 回復「h」或者「幫助」,查看幫助;

開發者已開通多個微信群交流學習,請加若飛微信:13511421494 進群

開發者:KaiFaX

相關焦點

  • 你的表單害你沒訂單?9個常見的表單設計問題
    在網站中,表單是使用者跟我們溝通的主要橋梁。透過表單,使用者可以買東西、訂閱新文章、更新資料……可以說網站最重要的功能,都是靠表單來完成。然而這個跟顧客打交道的重要環節,我們真的有做好了嗎?以下分享的是一些常見的表單設計問題,以及我們可以怎麼修正。表單設計好,可以差多少?
  • 攜程技術專家:資料庫壓力降低90%,訂單緩存系統架構實踐
    不僅業務上帶來的流量壓力,技術改造也帶來了更多的流量,如微服務化的推進、機票前後臺訂單業務解耦,不可避免地使得訂單查詢系統被依賴程度進一步提高。而且我們沒有使用類似GraphQL 的技術,之前的前後臺服務直連資料庫,現在使用查詢API,沒有高度定製化產生了數據冗餘,帶來額外的查詢壓力。
  • 設計沉思錄|移動端複雜表單的減負與提效
    編輯導讀:我們上網經常會碰到各種各樣的表單。註冊帳號要填表單,網上購物要填表單,登錄郵箱要填表單……好的表單設計能給網站增加註冊量,面對複雜的表單,設計師如何對其重新設計,為用戶減輕負擔、提高表單效率和成功率呢?本文作者結合負責的具體項目案例,對此進行了分析總結,與大家分享。
  • 消費-淘寶訂機票可靠嗎在淘寶上如何訂機票
    現在每到節假日就會出現購票困難購票擁擠的現象,造成的局面會是一票難求啊,所以在網上也有越來越多的軟體APP可以方便大家網上訂票不用排隊擁擠了,有人說也可以在淘寶上訂機票的,那麼淘寶訂機票可靠嗎?淘寶訂機票可靠嗎據了解淘寶商城中的訂票商都是經過審核的,機票在淘寶上只有淘寶官方在賣,其他人是不許賣機票的,所以信譽是肯定沒問題的,訂票成功後,在航班起飛前90分鐘左右到各航空公司相應櫃檯,出示身份證就可以辦理登機手續。
  • 反應解耦: 推動燃料熱化學轉化技術創新發展—新聞—科學網
    煤炭、生物質等碳氫燃料熱解、氣化、燃燒等熱化學轉化(熱轉化)過程涉及複雜的化學反應體系,發生許多相互作用的化學反應,單個化學反應被稱為「屬性反應(Attribution reaction)」。燃料熱轉化領域的「解耦」指調控屬性反應間相互作用、實現熱轉化過程優化的技術方法。
  • 中國移動將OpenUPF和N4解耦工作推入3GPP國際標準
    中國移動將OpenUPF和N4解耦工作推入3GPP國際標準 2020-06-13 19:20:39 來源 : C114通信網
  • 界面設計方法(5):表單功能的設計
    一般在表單上不直接設置操作功能,也不用於輸入數據,表單功能具有以下的一些的特點(以下簡稱為:表單)。1)粒度每張表單內容都是根據表達的題目而確定的,粒度決定的參考建議:用戶需求:在一張表單上呈現哪些內容主要是由用戶確定的,單據類會比較簡單,報表類會比較複雜。
  • 基於H∞混合靈敏度的飛彈解耦控制器設計方法
    近年來,隨著控制理論的發展,多種解耦控制方法應運而生,如特徵結構配置解耦、自校正解耦、線性二次型解耦、奇異攝動解耦、自適應解耦、智能解耦、H∞解耦,變結構解耦等,其中文獻[4]採用多變量頻域法,將耦合的MIMO系統化為一系列的SISO系統,再用經典頻域法分別設計,實現了BTT飛彈
  • 營銷低價機票 淘寶叫板攜程
    中國最大的電子商務網站運營商阿里巴巴集團說,將擴大其旅行業務,把國際機票銷售包括進來,並計劃與中國最大的在線旅行公司攜程網抗衡。  阿里巴巴旗下零售網站淘寶網周三開始在線銷售國際機票,並計劃提供比攜程旅行網和其他競爭對手更低的票價。
  • 賣家取消訂單卻"收取"貨款 淘寶支付規則存"文章"
    網上預訂出國酒店機票,訂單取消錢被騙   2012年8月,被害人劉某所在公司的老闆,讓她上網預訂到馬爾地夫旅遊的酒店和機票。8月29日,劉某在淘寶網上找到一家名為「馬爾地夫酒店」的店鋪,店主的用戶名叫「開心之旅trip」,該店鋪內有一款產品為「馬爾地夫四季庫達呼拉島(Four Season at Kuda Hura)預訂」。
  • 乘客曝網購機票竟超原價 淘寶稱賣家已說明
    【花2200元淘寶購機票 票面顯示1850元】「我們一行9人原定春秋航空機票從上海飛往三亞。因為颱風影響,原定8日的飛機被取消,不得以只能通過手機進入淘寶網,訂購8月9日的機票。當時支付的機票價格為每張2200元(不包括機建與燃油費)。
  • 中國移動在線發布5G OpenUPF白皮書暨N4解耦規範(Phase1)
    會上發布了5G OpenUPF(面向行業的5G UPF及N4接口開放合作夥伴計劃)白皮書、N4接口解耦規範(Phase1),明確了5G OpenUPF可管、可控、靈活、開放的發展目標。中國移動制定了面向垂直行業N4解耦的系列規範,努力解決目前UPF融入垂直行業存在的「三大障礙」,即設備功能複雜、容量起步過大、與SMF同廠家綁定,N4解耦有利於降本增效的滿足行業客戶的多樣化訴求。中國移動將結合龍頭示範項目,進一步摸清行業需求、明確部署策略、梳理商業模式,積極推進5G OpenUPF在行業場景的試商用,早日實現5G技術融入百業、服務大眾。
  • 碎片數據收集利器:結構化動態表單設計思路
    傳統的區域化基本公共衛生系統正在經歷這樣的劇痛,當然其他行業比如金融的部分業務同樣面臨相同問題(本人只經歷過這兩個行業,見諒),如何在紛繁複雜的業務環節中抽離出四兩撥千斤的數據模型,除了滿足日益頻繁的業務調整外,還能將數據完整的、標準的存儲並利用起來,是後端產品經理的安身立命之本。
  • 技巧分享|關聯表單
    使用得帆雲的關聯表單組件,可在當前表單中關聯其它表單,支持在當前表單中直接操作他表數據,實現多個表單同時管理。下面我們將通過應用「項目管理」來介紹關聯表單組件的使用方法和應用場景。可以在「項目管理」中關聯「風險管理」表單,這樣在項目管理表單中就能輕鬆查看到風險管理中的數據了。首先,新增關聯表單組件。
  • 零代碼市場正以五倍增速擴大,表單類應用搭建平臺「簡道雲」想要...
    通過零代碼應用搭建平臺,企業客戶只需積木式的搭建就可以建設企業級的業務系統,成本低,速度、開發和迭代的敏捷、迅速是平臺的最大特點。「簡道雲」作為一款線上零代碼應用搭建平臺,主要為沒有專門軟體的長尾行業、長尾領域的非技術人員提供服務,使用者通過搭建、拖拽、模板等方式,就能搭建出符合需求的個性化管理應用。
  • 淘寶直播在衝刺最複雜的人工智慧技術!
    虛擬主播看起來只是一個3D動畫,但背後,是人工智慧領域最複雜的技術應用。為什麼要這麼說呢?02提到人工智慧,你會想到什麼?是的,人臉識別是目前火熱的AI應用,但人臉識別大多是視覺技術;siri?各個手機附帶的人工智慧,以及各類硬體產品,基本是依賴語言識別技術;自動駕駛?比起上述兩個,自動駕駛是更複雜的AI應用,但也是綜合了語言、圖片等技術的大數據應用。
  • 一個複雜系統的拆分改造實踐!
    需要多維度的思考、實踐。一個是技術層面,通過與pd以及開發的討論,熟悉現有各個應用的領域模型,以及優缺點,這種討論只能讓人有個大概,更多的細節如代碼、架構等需要通過做需求、改造、優化這些實踐來掌握。複雜問題能否拆解?實際操作時是否有預案?」,應用拆分在具體實踐過程中比拼得就是細緻二字,多一份方案,多一份預案,不僅能提升成功概率,更給自己信心。2.6 放鬆心情,緩解壓力收拾下心情,開幹!
  • 同是經濟艙機票價差一倍「被掉包」 乘客索要3倍賠償遭拒
    市民韋先生去年12月19日通過阿里旅行網訂兩張機票出遊,旅行回來後經查詢發現,他訂的機票是1680元的B艙,而實際持有的是910元的R艙機票,加上折扣,兩張票差價1622元,而原先支付訂單的高艙位票卻被人退票,換成了實際出行時的低艙位票。
  • 1號店11.11:從應用架構落地點談高可用高並發高性能
    但當業務開始變得複雜、人員規模爆發式增長,這種強耦合強依賴帶來的弊端就成了巨大的瓶頸,代碼耦合度高互相衝突、出錯概率和事故概率明顯提升,業務需求不能快速響應,SOA治理迫在眉睫,解耦和去依賴成為第一需求,於是Service化成為第一前提。2.2 SOA治理- Service日誌是保障1. 做Service首先是規劃,Service規劃的第一步首先考慮什麼?
  • 淘寶怎麼取消訂單
    直接登錄到自己的淘寶帳號,我的淘寶-已買到的寶貝。在已買到的寶貝中可以看到剛剛拍下來的寶貝。如果你剛剛拍,還沒有付款,那麼這個時候比較好辦的。直接點擊「取消訂單,」,選擇一個取消的理由即可取消。如果你已經付款,這時候稍微比較麻煩些。點擊阿里旺旺的頭像和店家直接溝通,表明你想取消訂單。