天天看點

前端開發的思考--看起來簡單,做起來難

今天和網上的朋友聊到了前端開發,這位朋友真是一位大師級人物,聊聊幾句話,幾乎就概括了整個前端的開發工作。

我整理了一下,前端的開發工作大緻包含3點:

1. 前後端的資料互動

2. DOM操作

3. 子產品化設計

這3點将我們前端雜亂無章的開發工作梳理了一遍,至少讓我們的思路得到片刻清晰,是的至少是片刻清晰。讓緊繃的神經得到片刻放松。

我個人從事開發工作有15年時間,其中大概有5年左右的Web前端經驗。 至少到目前為止,還沒有一個項目能夠給我上面3點的那種輕松的感覺。這就像我們看房子的樣闆間,家具擺放得賞心悅目,但當我們真的住進去之後,才發現各種問題。

的确,軟體開發的實際情況從來都沒有過看起來如此簡單過。現在就讓我們進入這個樣闆間轉轉。

前後端的資料互動

我們至少可以通過以下庫來實作前後端的資料互動

  1. AngularJs的http
  2. JQuery的ajax
  3. axios
  4. WebSocket

 對于AngularJs的http,如果你用AngularJs進行開發,一般都使用http子產品。據我了解,大多數類似于angularjs的重量級js架構,都會有其自身的前後端資料互動子產品。

對于後面3種,它們一個比一個專。

JQuery的ajax是通過JQuery這個輕量級的Js架構釋出的。JQuery作為Js世界的老大哥,很多現有的其它js架構都會跟jQuery相容 。而JQuery又有着很強的DOM操作能力。是以,當JQuery作為項目前端架構的一部分時,通常也會使用到JQuery的ajax來實作前後端通信。

axios則隻專注于http的資料通信,它可以在nodejs和浏覽器環境下運作。支援Promise對象。我之是以在這裡提到axios,是因為我曾經使用過它,個人感覺api設計得不錯。但事實上,在npmjs的網站上,類似的庫還有很多。

DOM操作

這方面的技術,個人認為,鼻祖就是JQuery。以前我也試過ExtJs,Dojo,裡面也有類似的DOM操作庫。

DOM操作的目的是展現資料。關于資料展現,最初就是簡單的表單和清單,後來随着web應用的日漸繁榮和需求的日益複雜,出現了WYSIWYG編輯器和類似于JQueryUI, Bootstrap的各種庫。最終,這些UI庫隐藏了DOM操作的細節,隻暴露出API給開發人員調用,使得開發人員隻用正确配置和調用接口,就可以實作很酷的界面效果。

目前,就我個人的觀點,最好用的UI庫是Boostrap,它不僅提供了目前常用的Js插件,還提供了一套頁面布局的标準。這些都和DOM的操作緊密相關。

當然,EasyUI也是一個很強大的Js庫,提供了豐富報表和界面插件。限于個人的見識,我相信還有不少類似于EasyUI的Js庫。在這些Js庫的幫助下,可以完成我們日常需要的各種複雜界面。

我個人認為,DOM的操作可以分為3個層次:

  1. 能夠使用Js庫來完成DOM的操作
  2. 能夠解決Js庫的沖突,Js庫的樣式問題和Js庫的浏覽器相容性問題
  3. 能夠自己寫Js庫來完成DOM的操作

子產品化設計

 我對Js的子產品化設計最初是從Js的閉包開始的,然後接觸到了requireJs,然後是AngularJs。

最初的子產品化設計僅僅是為了管理日趨龐大的代碼,随着requireJs的出現,又出現了子產品加載的能力。個人認為,無論子產品化的技術怎麼發展,子產品化設計都離不開業務分析的結果,子產品化設計是技術與業務的結合,業務分析在這個階段必不可少。

如果你的項目已經使用了angularJs這樣的重型架構,那麼它已經為你提供了子產品化設計的技術支援。如果你想自己去建構項目的子產品,那還是推薦使用requireJs或者seaJs。

是以,從技術層面上來說,子產品化設計依賴于各種Js架構/庫提供的技術支援,了解并掌握類似于AngularJs, requireJs的子產品定義就可以了。而從業務層面上看,則可以參考Eric Evan 的Domain Driven Design這本書。

個人認為,子產品化的設計核心價值是讓系統得到有序建構,其衡量标準是讓子產品之間的依賴盡量簡單,其實作的方式是讓子產品功能範圍與業務的相關範圍得到最大程度的比對。是以,子產品化設計的切入點就是對先對業務模型進行設計。

-------------------------------------

目前來說,這三個方面基本闡述完畢,看上去也比較單純。這裡借用一位我們的祖先老子的一句話:道生一,一生二,二生三,三生萬物。貌似什麼事情,過了3就會變得複雜起來。

下面給出一個例子,來展示這3個方面扭在一起時的情況。

以TypeScript的Angularjs 2項目為例。

假設我們定義了serviceA用于前後端資料互動。

定義了componentA用于資料展示,即dom的操作。

定義了一個module,用于存放serviceA和componentA,用于子產品化設計。

個人認為,用于前後端資料互動的service定義,在javascript的動态語言環境下,不過就是一個管道,甚至不用去考慮傳輸的資料結構是怎麼樣的,隻用關心如何正确傳入參數和正确擷取輸出。而真正要關心的是擷取的資料如何正确綁定/顯示到界面上,界面上的參數如何正确綁定到service要傳入的參數上面。這時,我們會想到component的定義,或者是在界面上,會展示/編輯什麼資料。從理論上講,背景傳到前台的資料應該直接綁定到界面上就結束了,資料沒有理由增加或減少。唯一需要做的是在前台定義個model來綁定到界面設定的參數上,最後在查詢時,将這個model傳給service,但有時,這一步都可以被省略。

到目前為止,我們都還是理論上的推導,但在實際開發中,這些僅僅是保留在大腦裡還未付諸實施的想法。當我們開始動手編碼的時候,我們會遇到各種各樣的問題。

  1. 子資料的處理
  2. 資料選項的展示
  3. 資料驗證
  4. 根據資料A推導出資料B的資料展示

子資料的處理需求一般來至于業務的逐漸完善。當我們完成藍圖的第一個版本設計的時候,我們建構的資料模型是抽象的。抽象意味着任何一個點在實施的時候,都有可能再向更深的邏輯層次展開。

是以,随着業務的逐漸完善,這種抽象到更深層次的展開就不可避免。

這種情況帶來的幹擾是資料處理出現了分支。出現了分支,就會有分支展開和分支回歸操作。這種展開和回歸的操作具體到代碼中,它幾乎會同時影響到我們上面提到的3個方面。

在前背景的資料互動方面, 會影響到定義的model的結構,會添加新的結構來映射子資料。

在DOM的操作方面,會定義出新的區域來展示和操作子資料,而這個動作無疑會引入新的,和業務關系不大的膠水代碼,而最終貢獻了代碼的複雜性。

在子產品化設計方面,你需要決定是否設計出新的component來存儲相關的代碼,如果你決定是否定的,那麼就要修改處理主幹資料的component,如果你決定是肯定的,那麼整個系統的結構就會受到一定程度的影響。

資料選項的展示無論是在“先天的”設計階段還是在“後天的”開發階段都會影響到開發的三個方面。

資料選項和資料字典不同在于,它是根據目前的上下文,動态生成的。它涉及到事件的關聯處理,DOM的動态更新以及預設選項的處理。我曾經遇到過的複雜情況,事件的關聯超過了4級。而這些關聯處理都是膠水代碼,不易于維護。

資料驗證是一種技術挑戰。資料驗證的方式有:

  1. 前端的資料驗證
  2. 後端的資料驗證

實時的資料驗證對技術要求比較高,它要求對使用者的每一次鍵盤敲擊進行資料驗證,AngularJs 2的ValidatorDirective可以助我們一臂之力。對于簡單的驗證邏輯,我們可以直接将其放在自定義的Directive裡面,對于複雜的業務邏輯,可以放在Service裡面。雖然,我們已經有了清晰的思路來處理驗證代碼,但是對于這些驗證的配置,需要不少的時間,當然也會貢獻出不少代碼。

儲存資料時的資料驗證發生在資料完成編輯後,将資料持久化之前的這個視窗中。随着現今類似于Angularjs前台架構的應用,很多時候,資料驗證也被放在了前台。但是,按照傳統的分布式系統的設計方式,資料驗證會被放在背景,這樣有利于業務邏輯在更大層面上的複用。

前端的資料驗證優勢在于速度快,後端的資料驗證優勢在于對資料的處理能力強。是以,通常情況下,我們要同時使用前背景的資料驗證方式,來一起解決問題。注意,這裡還有一顆地雷,就是前背景的驗證邏輯同步問題。

但不管是前端的資料驗證還是後端的資料驗證,最終都需要将驗證的邏輯展現在DOM上面。這使得前後端的資料互動和DOM的資料展示再一次擰在了一起。這裡再一次考驗架構師的真實能力,但無論怎麼設計,代碼的複雜性是以而再次增加。

根據資料A推導出資料B的資料顯示通常是開發後期追加的業務需求。個人認為它是對代碼結構沖擊最大的方式。它在處理上建立的分支首先會影響到已經穩定的結構。由于得響應某個事件來加載資料,是以,還必須為此添加額外的膠水代碼。而這段膠水代碼,會影響到前背景的資料互動,會影響到DOM的資料展示和操作響應,最終可能到處都被糊上了。

上面這些問題僅僅是從應用的業務邏輯實作來看的,還有無數的日日夜夜處理的浏覽器相容問題,特别是使用了類似于Bootstrap這樣的CSS架構後還遇到的浏覽器相容問題,這裡我就不多說了。

以上就是個人的一些想法,寫到這裡,我發現這裡既是結束,又是開始。既然都已經知道了這些問題的模式,那麼就有對應的解決模式,容我再想想,有時間接着侃吧。

上面寫了這麼多,都沒有一行代碼,如需代碼,請前往 https://github.com/cao5zy/restful_angularjs

口水話較多,限于個人的經驗,漏洞百出,還望大家多多指教。

轉載于:https://www.cnblogs.com/czy/p/thinking_in_frontend_development.html

繼續閱讀