1. 程式人生 > >響應式和函式式,兩個容易混淆的概念

響應式和函式式,兩個容易混淆的概念

響應式(Reactive Programming,簡稱RP)

在計算機中,響應式程式設計是一種面向資料流和變化傳播的程式設計正規化。這意味著可以在程式語言中很方便地表達靜態或動態的資料流,而相關的計算模型會自動將變化的值通過資料流進行傳播。

傳統的程式設計方式,是順序執行的,上一個任務沒有完成的話需要等待直至完成之後才會執行下一個任務。無論是提升機器的效能還是程式碼的效能,本質上都需要依賴上一個任務的完成。如果需要響應迅速,就得把同步執行的方式換成非同步,方法執行變成訊息傳送。這變成了非同步程式設計的方式,它是響應式程式設計的重要特性之一。

響應式程式設計有以下幾個特點:

  • 非同步程式設計:提供了合適的非同步程式設計模型,能夠挖掘多核CPU的能力、提高效率、降低延遲和阻塞等。

  • 資料流:基於資料流模型,響應式程式設計提供一套統一的Stream風格的資料處理介面。和Java 8中的Stream相比,響應式程式設計除了支援靜態資料流,還支援動態資料流,並且允許複用和同時接入多個訂閱者。

  • 變化傳播:簡單來說就是以一個數據流為輸入,經過一連串操作轉化為另一個數據流,然後分發給各個訂閱者的過程。這就有點像函數語言程式設計中的組合函式,將多個函式串聯起來,把一組輸入資料轉化為格式迥異的輸出資料。

響應式程式設計一方面在使用者介面程式設計領域以及基於實時系統的動畫方面都有廣泛的應用。另一方面,在處理巢狀回撥的非同步事件,複雜的列表過濾和變換的時候也都有良好的表現。

現在的App無論是H5、原生還是Hybird,都會和與資料事件相關的 UI 事件進行大量地互動,使用響應式程式設計會顯得更加得心應手。

這些年來前端比較流行的響應式設計,實際上它是指網頁能夠自動調整佈局和樣式以適配不同尺寸的螢幕。跟我們這裡談論的響應式程式設計是兩個概念。

函式式(Functional Programming,簡稱FP)

In computer science, functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data.

隨著硬體能力不斷提升,單核CPU的計算能力幾乎達到了極限,CPU進入了多核時代,程式設計師轉而通過併發程式設計、分散式系統來應對越來越複雜的計算任務。

然而併發程式設計並不是銀彈,做為一種基於共享記憶體的併發程式設計,多執行緒程式設計有常見的死鎖、執行緒飢餓、race condition等問題,而且多執行緒的bug難以重現和定位。

於是,函數語言程式設計開始興起。在函數語言程式設計中,由於資料全部都是不可變的,所以沒有併發程式設計的問題,是執行緒安全的。它將計算機運算看做是數學中函式的計算,主要特點是將計算過程分解成多個可複用的函式,並且避免了狀態以及變數的概念。函數語言程式設計雖然也可以歸結到面向過程的程式設計,但其思想更接近數學計算。

函數語言程式設計的特點:

  • 函式是"第一等公民":所謂"第一等公民"(first class),指的是函式與其他資料型別一樣,處於平等地位,可以賦值給其他變數,也可以作為引數,傳入另一個函式,或者作為別的函式的返回值。

  • 閉包和高階函式:閉包是起函式的作用並可以像物件一樣操作的物件。與此類似,FP 語言支援高階函式。高階函式可以用另一個函式(間接地,用一個表示式) 作為其輸入引數,在某些情況下,它甚至返回一個函式作為其輸出引數。這兩種結構結合在一起使得可以用優雅的方式進行模組化程式設計,這是使用 FP 的最大好處。

  • 遞迴: 用遞迴做為控制流程的機制。例如在Haskell的世界中,沒有變數賦值,流程跳轉,如果要實現一些簡單的功能,比如求一個數組中的最大值,都需要藉助遞迴實現。

  • 惰性求值(Lazy Evaluation): 它表示為“延遲求值“和”最小化求值“。惰性求值使得程式碼具備了巨大的優化潛能。支援惰性求值的編譯器會像數學家看待代數表示式那樣看待函數語言程式設計的程式:抵消相同項從而避免執行無謂的程式碼,安排程式碼執行順序從而實現更高的執行效率甚至是減少錯誤。 惰性求值另一個重要的好處是它可以構造一個無限的資料型別,無需要擔心由無窮計算所導致的 out-of-memory 錯誤。

  • 沒有"副作用"(side effect):指的是函式內部與外部互動(最典型的情況,就是修改全域性變數的值),產生運算以外的其他結果。函數語言程式設計強調沒有"副作用",意味著函式要保持獨立,所有功能就是返回一個新的值,沒有其他行為,尤其是不得修改外部變數的值。

既然函數語言程式設計已經能夠解決併發的問題,為何還需要響應式程式設計呢?

函式響應式(Functional Reactive Programming,簡稱FRP)

函式響應式結合了函式式和響應式的優點,把函式正規化裡的一套思路和響應式程式設計合起來就是函式響應式程式設計。

我們知道,傳統的面向物件程式設計通過抽象出的物件關係來解決問題。函數語言程式設計通過function的組合來解決問題,響應式程式設計通過函數語言程式設計的方式來解決回撥地獄的問題。

用傳統的面向物件來處理非同步事件不是很直觀,處理併發也是件麻煩的事情,所以才產生了函式響應式程式設計。

小結

函數語言程式設計和響應式程式設計是兩個不同的概念,剛接觸RxJava那會我也經常搞混兩者的概念。

兩者的結合函式響應式程式設計確實是給開發帶來了一種新的方式和思維上的突破。

參考資料:

  1. http://nicholas.ren/2015/06/24/lets-talk-about-reactive.html

  2. http://emacoo.cn/backend/reactive-overview/

  3. http://www.cnblogs.com/kym/archive/2011/03/07/1976519.html

  4. http://www.ruanyifeng.com/blog/2012/04/functional_programming.html

  5. http://janfan.cn/chinese/2015/05/18/functional-programming.html

  6. https://baike.baidu.com/item/%E5%87%BD%E6%95%B0%E5%BC%8F%E7%BC%96%E7%A8%8B/4035031

關注【Java與Android技術棧】

更多精彩內容請關注掃碼

0?wx_fmt=jpeg