如何設計和實現一個web app

web app簡介html

web app其實不算是什麼新鮮的東西,相比於傳統的web和傳統的app,web app這種web和app相結合的產物有的優勢以下:前端

1. 開發上web app更有便捷性,ios開發一上來須要安裝一堆東西,android開發也差很少,另外web app的學習成本要比平臺客戶端開發要低些,至少你不用去招聘ios和android程序員。只要具有基礎web開發能力的人均可以比較快上手。react

2. 部署方便,在不少狀況下,部署一個單頁web app只須要一個index.html頁面文件做爲容器和一個前端資源打包文件(通常叫bundle.js)便可,而後把index.html放在本身服務器項目路徑下,在其中引入bundle.js,至於bundle.js則能夠放在CDN上,更新web app就等因而上傳並刷新CDN緩存。這樣一來前端部署極其簡單,基本上不須要SSH到服務器去更換文件,也能夠避免本身的服務器傳輸比較耗費帶寬的前端資源文件。android

3. 單頁web app若是技術選型得當,開發和維護成本都相對比較低。ios

4. 能夠適應更多環境。程序員

凡事都有利弊,web app也有不盡如人意的地方,web app的主要缺點以下:web

1. 性能上不如原生app,這個不用多說,基本是不可改變的事實。ajax

2. 暫時還沒想到其餘的。編程

前期準備redux

首先要進行技術選型,根據做者的經歷,我選擇的是react+flux,flux是一種數據流的架構方式,嚴格來講它並非某一種特定的實現。比較經常使用的實現有facebook官方的flux實現,還有一些第三方實現(好比redux)。要注意的是,flux的具體實現基本不會影響到咱們的項目開發,具體選擇哪一個實現就看你的喜愛了(固然最好不要中途再作改變:D)。

那麼就要來簡單介紹一下react是什麼,react能夠說是一個改變前端生態系統的發明,傳統web開發中,咱們以頁面爲單位來設計模塊,若是有多個頁面都用到了某個功能,好比一個列表,那麼就要重複地寫HTML和JS實現它,代碼抽象程度很低,冗餘度很高,也不利於後期維護。react推出了UI組件的概念,讓web前端開發人員能夠封裝UI組件用於複用。

flux這種數據流架構思想其實也不是什麼新東西,可是真正在web前端大規模使用也是在開發人員使用react+flux以後的事情。flux制定了一些web前端數據獲取和分發的規則,雖然剛開始看上去比較複雜,可是一旦你理解了它的思想,其實很簡單,並且對於維護一個web app來講,react+flux能夠說是至關不錯的組合。

設計一個web app具體是在設計什麼?

剛纔談到了react+flux,其實UI組件的封裝和數據流的架構,它們都幫開發人員規定好了,咱們須要作的就是去好好運用它,那麼還有什麼可設計的呢?

仍是有的,並且很多。從技術角度來講,web app和ios app、android app這些原生app在技術設計上有不少共通之處:

1. 頁面生命週期管理
2. 公共函數的設計
3. 局部/全局事件和通知
4. UI組件API設計
5. 常量定義
6. 網絡請求
...

web app也具有一些原生app所沒有或不同的特性,例如app路由、JS(ES5/ES6差別)、使用/刷新CDN緩存、前端資源打包、快速部署等。

react+flux是怎麼工做的

因爲本篇文章並非react和flux的教程,因此只會大體介紹一下它們的工做方式。

下面是官方給出的一個flux工做流程圖:

詳細版:

簡單解釋一下flux的工做流程:

在第一張圖中,有兩種流程:

1. Action->Dispatcher->Store->View

2. View->Action->Dispatcher->Store->View

在Action->Dispatcher->Store->View中,能夠經過調用Action中的方法來執行一項操做,這個操做能夠是向服務器請求數據,或僅僅在本地改變數據,操做完成後,Action會通知Dispatcher,而後由後者來分派動做和數據。在Store中,事先註冊好對各個類型事件的回調函數,當Store接收到Dispatcher分發來的事件和數據時,就執行一些更新操做。另外View能夠對Store註冊監聽器,一但Store中的數據有變化,會當即執行View預先設置好的監聽器回調函數,這通常會是一個更新View的操做,這至關於一個發佈-訂閱模式。

在View->Action->Dispatcher->Store->View中,其實是說指用戶和View之間的交互致使數據變動(無論是請求服務器仍是本地數據改變),其餘操做和Action->Dispatcher->Store->View基本同樣。

光看這些是十分抽象的,若是沒有深刻去看一個demo或者本身實現一個項目,確實有點很差理解。我將在後續介紹flux和react。

本篇中react+flux基本介紹到這。下面要談談具體設計。

具體設計

一個web app無非就是顛來倒去地作如下幾件事:

1. 調用網絡API
2. 展現頁面
3. 數據本地存儲(這裏通常指非持久化的那種,這和原生app有所不一樣)
4. 接受用戶輸入並反饋

做爲技術人員,咱們首先要明確幾點:

1. 明確地知道業務放須要什麼。
2. 劃分功能模塊。
3. 弄清楚各個問題之間的依賴關係,制定模塊之間的通訊規範。
4. 適當考慮項目將來走向,對架構設計留有餘地。
5. 分析風險。
6. 考慮如何解決依賴關係中最基礎的部分,先實現基礎模塊(或者至少你要先對此有個大體的設計),不斷在此基礎上完善整個架構。這部分開發人員會花費比較大的精力去作,由於這影響到整個項目將來的幾乎全部事情。同時在這個過程當中不斷審視架構是否合理,及時調整。
7. 單元測試,性能測試(若是項目須要且有時間的話)。

項目文件結構

好的開發習慣其中一個就是要制定清晰的項目文件結構,而且從始至終保持下去。

適當的文檔描述

若是可能的話,適當寫一些幫助性的架構文檔,用簡潔明確的詞語傳達你想要表達的,讓後來的程序員能夠快速上手。

思路和方法同一,不搞多元化

在一個項目中,對同一類事情應該有一個統一的處理方法,包括代碼風格、變量和方法的命名規範、調用規範、流程規範等,事先制定出來,而且要求全部人都要遵照。

儘可能少的橫向依賴,儘可能減小跨層訪問,下降模塊間耦合度

這部份內容react+flux已經幫咱們作了很大一部分。

對業務方該限制的地方有明確的限制,該靈活的地方要給業務方創造靈活實現的條件

能夠經過良好的設計來保證這一點。

接下來會對劃分功能模塊、模塊間通訊規範、解決依賴關係這幾個方面進行說明。

功能模塊的劃分

在react+flux的項目中,不談具體業務的狀況下,有幾個大的基礎模塊是必定要考慮的:

1. 展現模塊
2. 網絡請求模塊
3. 本地存儲模塊
4. 路由模塊
5. 公用模塊

1. 展現模塊

這是用戶能直接看到的東西,咱們用react封裝各個UI組件提供出來,也能夠引入第三方UI組件,這自己已是一種進步,讓咱們能夠在web前端「面向組件編程」,所以對UI組件的處理就尤其關鍵。ES6語法下,咱們能夠用extends react.Component來創建一個UI組件,而後在組件「類」中寫初始化方法、渲染方法、生命週期函數、事件回調等方法,而後把它做爲一個總體提供出去,這裏就涉及到UI組件API的設計,UI組件能夠接受屬性值,這些屬性應該儘量的少和命名清晰、簡單,保持簡潔性頗有必要。另外組件的展現離不開CSS和一些資源文件,做爲一種封裝,把CSS、圖片等資源文件一併放在這個UI組件的文件夾下也是頗有必要的。

2. 網絡請求模塊

web app網絡請求全靠ajax,在和服務器交互時,應該和服務端約定好返回數據的格式,如錯誤代碼的含義、出錯信息、詳細的數據格式等,而且頗有必要在web app端作一層封裝,好比封裝出一個request模塊,在服務器返回數據後首先解析返回數據,若是出錯就報錯,成功就執行用戶回調函數等。這部分做爲整個項目對外的接口應該考慮到全部可能的網絡狀況:服務器致命錯誤、普通錯誤、成功、超時、無網絡等。

3. 本地存儲模塊

這部分主要交給flux處理,咱們須要作的就是設計本地數據的結構,使其儘可能合理並適應多種應用場景。

4.路由模塊

react+flux的單頁web app通常採用react-router做爲路由,這能夠省下你很多時間和精力,react-router是一個很是成熟和優秀的路由模塊。

5. 公共模塊

公共模塊通常包括但不只限於:公用函數、helper、常量定義、應用級別的功能(如展現loading框、警告框、確認框這些)。這部分功能也很重要,好比loading框,咱們在發起網絡請求時會展現它,數據返回時它會消失,那麼這個框的出現就與上面說到的網絡模塊有關係,警告框和確認框也是經常使用的東西,這些組件均可應該在app層面上進行設計和整合,而不該該放在各個UI組件內部,由於這個是一個app中的通用功能。

模塊間通訊規範

在react+flux中,使用一種單向數據流的方式來分發數據,這就讓整個數據走向很是清楚,咱們的web app模塊間通訊規範就是根據這個單向數據流的思想來的。

解決依賴關係

react+flux中處理依賴關係時,用的比較多的方式無非3種:顯式引入、基於事件(發佈-訂閱模式)、回調函數。

在要向模塊中引入其餘模塊時(import),使用顯式引入,這種依賴關係最強也最明顯。若是是依賴關係沒有那麼強,能夠考慮用後面兩種,這有助於代碼的簡介和模塊解耦。

基於事件(發佈-訂閱模式),舉個簡單的例子,flux中當Store中的數據變化時,要通知相對應的View更新頁面,典型的處理方式是讓Store成爲一個EventEmitter,同時View對該Store addChangeListener,即成爲它的訂閱者,當Store改變時會自動調用該View的監聽回調,讓View更新界面。

基於回調函數,有一個很是典型的用例,在設計通用的警告框和確認框組件時,有時咱們須要在用戶點擊「肯定」和「取消」按鈕時作一些事情,固然也可能什麼也不作。這時候咱們不要忘了JS中函數是一等公民這件事,咱們能夠把事件處理函數傳遞給警告框和確認框組件,這樣就很巧妙的解決了跨組件、跨模塊通訊而不會使模塊過於耦合了。

相關文章
相關標籤/搜索