本文由 Shaw 發表在 ScalaCool 團隊部落格。
上一篇
1.1.3 響應式程式設計
響應式程式設計是一種基於資料流以及傳播資料變化的程式設計範例。例如,考慮表 1.1 中所表示的電子表格。
單元格 C1 以如下的方式來定義:
C1 = A1 * B1
如果我們在電子表格中執行上述例子,一旦 A1 或者 B1 的值發生改變,那麼 C1 的結果將相應地作出改變。因此電子表格背後的程式語言允許我們定義資料之間的關係,那些資料將會在電子表格中傳播變化。
為了實現一個實時的電子表格應用程式,比如 Google Drive 中的電子表格,我們將會利用一些底層的概念(諸如事件)去進行構建:當使用者改變單元格 A1 的值時,會觸發一個事件。然後所有與 A1 有關的單元格,比如包含我們表示式的單元格 C1就會對該事件做出響應,該單元格將會重新計算自身的值然後將新的值顯示出來。這個過程將完全對使用者隱藏,因為使用者只關心單元格中值之間的關係。
在 Web 應用程式開發方面,這種技術越來越多地用於前端應用程式的開發。比如 KnockoutJS、AngularJS、Meteor 以及 React.js 等工具都使用了這種模式。開發者不需要關心在特定 DOM 元素上宣告的監聽器的細節,他們只需要描述資料的變化是如何通過使用者介面進行傳播的就可以了。採用這種模式使得如何去實現響應式使用者介面變得簡單化了。我們將在第8章中探討響應式使用者介面。
在服務端也能找到類似的抽象,其中事件起著關鍵性的作用。比如「響應式流」,她旨在為 JVM 上的非同步流處理提供一個標準介面。關於這種新的方式我們將會在第9章詳細討論。
1.1.4 響應式技術的出現
這些年來出現了許多技術和框架,她們都有一些共同點,根據這些共同點,我們可以將其歸為響應式技術。但是開發響應式應用並不僅僅是簡單地使用響應式技術,這點將會在後面介紹。但是所採用的技術必須滿足許多先決條件用以支援響應式的行為,尤其是非同步和事件驅動程式碼執行的能力。
微軟的 Reactive Extensions (Rx; rx.codeplex.com/)是一個用於編寫基於非同步以及事件驅動程式的類庫。你可以在 .NET 平臺以及其他平臺(例如 JavaScript)上使用它。在 Node.js(nodejs.org)上使用 JavaScript 去構建非同步的、基於事件驅動的應用程式現已非常流行。同樣,在 JVM 上也有大量的類庫支援非同步以及事件驅動,比如 Apache MINA (https:// mina.apache.org) 以及 Netty(netty.io)。
這些底層技術都提供了構建非同步和事件驅動應用程式的基本工具,但是要使一個 Web 應用達到一種成熟完備的狀態還需要做很多工作。一個成熟的應用程式必須要能夠兼顧許多方面,比如程式碼組織、檢視模板、客戶端資源(例如樣式表和 JavaScript 檔案)的引入和組織。還有資料庫的連線以及系統的安全性等。當下有許多所謂的全棧式 Web 應用框架,其中還有少部分採用了響應式技術,但是隻有極少部分擁抱了響應式技術的原理和核心,她們通過採用響應式技術來從根本上去構建 Web 框架。
全棧式框架關注一個應用程式在構建以及部署過程中所涉及到的所有層面:客戶端UI技術(或整合方式),伺服器端業務邏輯,身份驗證,資料庫訪問整合以及各種通用模組的類庫(如遠端 Web 服務呼叫)。在響應式應用程式中,所有這些層都必須遵循相同的非同步呼叫和錯誤恢復的原則。
Play 框架是迄今為止 JVM 上唯一的一個全棧響應式 Web 應用框架。其他諸如 Lift (http://liftweb .net)的全棧式框架為 web 應用程式的開發提供了一個很好的選擇。但是她們沒有將非同步,故障恢復能力和可伸縮性作為主要的目標來設計。
Play 是基於 Netty 來構建的,並通過使用「響應式流」所提供的非同步流處理來支援其響應式行為(如圖 1.1)。
Play 通過使用 sbt 構建工具來處理 web 應用程式開發的典型問題,例如客戶端資源處理、專案的編譯和打包。並且 sbt 還提供了許多有用的類庫來解決諸如 JSON 處理和 Web 服務訪問之類的常見問題。另外她還提供了許多外掛來實現對資料庫的訪問。在本書的剩餘部分中,你將學習到如何利用 Play 的高效性來構建響應式 web 應用。
現在我們來進一步瞭解 web 應用程式是如何工作的,以及如何去利用計算機資源來理解為什麼響應式 web 應用程式的非同步、事件驅動的行為是必要的。