軟體設計方法論:流式編程與pipeline

許恆修 | Heng-Shiou Sheu
7 min readFeb 17, 2021

Functional reactive programming

首圖

前言(preface)

近幾年來,Reactive programming(響應式編程)的威力已被廣泛接受與使用,但是其背後的概念過於數學,導致實作上常常是一知半解的,我自己也學了很久才或多或少知道怎麼將 Reactive programming 進行圖像化,這套方法在公司內一直做使用,每當有新人進來時,都需要灌輸他們這些知識,為了讓未來的自己方便些,就先把教學寫著,方便新進員工吸收。

為何需要 Reactive programming

本段落將說明為何 Reactive programming 為何重要,並使用生活中例子來做對應。

我用生活例子舉例說明 Reactive programming ,舉例來說:我在幼稚園跟小朋友說「把散落滿地的積木收好,收好之後來跟我說」,這時候,我就等待小朋友收完之後來跟我說就好,而不是每隔幾秒鐘去問小朋友說:「積木收好了沒?」「好了沒?」「好了沒?」一來不但自己會累,小朋友也會爆炸,當小朋友回報說「收好了!」,我們這時拿出棒棒糖來獎賞他。這正好體現 Reactive programmgin 當中的 message-driven,讓萬物都是事件。我們是被動式的等待事件發生,而非主動式的不斷去詢問。

看待資料如同水流,看待函式如同水管

本段落將介紹如何看待 Functional reactive programming(FRP) 當中的資料處理方式以及思維,用接水管小遊戲讓腦中有整體串流概念後,接著講述 FRP 的特性。

不曉得各位有沒有玩過接水管小遊戲,遊戲內容是畫面上會有 16 * 16 的格子,格子中間會有許多不同造型的水管(pipe)可以做使用,有些只能左轉,有些只能走直線,有些甚至是可以像十字路口一樣,上下左右都通行,遊戲目標就是讓某個地方開始的水源,經過這些水管(pipe)之後,抵達目的地。

Img Credit: https://www.youtube.com/watch?v=n5M3GIY52FA&ab_channel=Lagged

我在說什麼?我在講 Functional reactive programming,遊戲中的水管(pipe)就是Pure Function(純函數),每丟一次相同的輸入到 pure function 中,都會得到相同的結果,而且不會有任何 side effect(額外影響),而水就是資料流,我想這是淺顯易懂的。

每個水管要做的事情也很簡單,就是去 subscribe(訂閱)某一個水管,同時也可以讓其他水管 subscribe 自己,subscribe 概念是什麼,就是當水管有水流出來的時候,我再做反應就好,如同一開始幼稚園中收積木小朋友的故事一樣,我是等到小朋友回報之後我才給棒棒糖。那身為水管的應個職責就是把水源送出去,出去之後的事情我就不管了,因為那不是屬於我這個水管的 scope。

設計流程

本段落將仔細說明何謂 pipeline 的設計方法,前面章節都是講述觀念,是用來建立基礎,讓各位在閱讀本段落時,不會感到突兀且茫然。

剛剛看過接水管遊戲,腦中應該有整體串流的模糊畫面,抓好那份感受,我們要用他來規劃程式了。

這邊我們使用最常見的登入畫面來做介紹,畫面上有兩個輸入框(email & password)、一個送出(submit)按鈕,情境是當 email 及 password輸入框都填寫好之後,submit按鈕才可以做按壓。如果只有其中一個是有填寫的話,則 submit 按鈕是無法進行按壓的動作。

初始畫面
成功畫面
失敗畫面

那要怎麼規劃流程呢?

首先,拿出紙筆,在紙的兩端分別寫上「已知」「想知」,下方各繪製長長一條直線。左邊是過去為已經知道的事實,右邊是想知道的結果。

想知、已知

現在我們已經知道有三個按鈕會出現在畫面上,email輸入框、password輸入框、送出按鈕,這三個分別寫在「已知」那條線當中。其中 使用 emailInput、PWInput、submitBtn 做命名。

寫上三個按鈕

這邊就需要發揮人的能力了,審視一次情境,我們想知道的是送出按鈕是否可以點擊了,而畫面上的按鈕僅僅是個顯示畫面,還需要個按鈕狀態來表明是否能夠點擊,所以在想知那端寫上 submitBtn 同時給定一個 displayState,由於 送出按鈕是由 displayState 驅動的,所以邏輯上知道 displayState 是在 submitBtn 之前。

按鈕狀態

目前為止的進展,應該是淺顯易懂的,希望你能夠跟上。接下來繼續往下推演,情境中,是要去監聽 email & password 是否有填寫的,所以我們弄個邏輯後面用來監聽 emailInput、PWInput 的變動狀況,使用 emailInputChange、PWInputChange 作為命名。

監聽輸入框變化

這個階段的你,一定知道說,剛剛的情境中,我們是要兩個輸入框都有值時,按鈕才可進行按壓,就目前圖上來看,我們可以監聽輸入框變化,也有按鈕顯示狀態,現在缺少的是中間一個用來判斷是不是都有值且會去改變按鈕狀態的地方,這邊我用 changeStateLogic 作為命名,功用就是去監聽輸入框變化這件事情本身,而如果條件達成之時,我才去驅動按鈕狀態。如同之前的幼稚園小朋友故事一樣,我拿到積木完成的訊號之後,才做出反應。

邏輯處理

這樣看起來一切都妥妥的了,弔詭的地方在於已知那端的 submitBtn 沒有用上,這可能是不必要的按鈕或著是沒用上的物件,在這個登入頁面的情境中,送出表單這件事情是必定存在的,所以屬於後者。由於按鈕本身也可以被當作一個事件,因此這邊直接連過去右邊的想知就可以。

總體流程規劃

至此,這個章節中你已經學會如何透過簡易的登入畫面配合 pipeline 思維進行程式規劃與設計。

實作範例介紹

本章節當中,我們將使用實際程式情境來介紹方才介紹過的 pipeline 設計方法,本次所用採用的案例為簡易計數器(Simple Counter)

這邊我們採用當下時尚時尚最時尚的 Reactive programming 做說明好了,同時也是每個軟體工程師在接觸程式必須經過的流程,計數器。閱讀至此的讀者們,希望可以自己先嘗試做過一次,再繼續往下閱讀。

「施工中」

結語

本文中介紹了 Reactive programming 概念、Functional Reactive Programming 概念、Pipeline 設計方法,希望至此你已經學會如何看待 Functional Reactive Programming 且搭配 Pipeline 設計方法來規劃程式。

參考資料

  1. [響應式宣言](https://www.reactivemanifesto.org/)
  2. [可視化編程](https://www.luna-lang.org/index.html#Overview)
  3. [可見即所得資料處理法](https://www.linkedin.com/pulse/wysiwyg-data-processing-pipelines-sreeni-iyer/)
  4. [Rxjs&Stream 應用](https://codecraft.tv/courses/angular/reactive-programming-with-rxjs/observables-and-rxjs/)
  5. [函數式反應編程](Functional Reactive programming)](https://gabriellesc.github.io/teaching/resources/FRP_slides.pdf)
  6. [為何 reactive programming 重要](https://www.youtube.com/watch?v=49dMGC1hM1o&ab_channel=CodingTech)
  7. [登入畫面](https://labs.thisdot.co/blog/form-validation-using-rxjs-and-typescript)

--

--

許恆修 | Heng-Shiou Sheu
許恆修 | Heng-Shiou Sheu

Written by 許恆修 | Heng-Shiou Sheu

AI研究員 @喬泰科技,軟體工程師@微光國際,業界講師 @FCU 創能學院,Co-Founder @圖靈文本。專注將科技應用於改善生活中,持續性分享軟體架構設計、前沿人工智慧研究、公司治理等觀念。整合科技、人文思維於一體。聯絡 📪 hengshiousheu@gmail.com

No responses yet