工作紀實・第六週

哎呀呀,上週末有點忙就拖到現在了

第六週有兩個重點突破,雖然有些東西在當時還沒有完成,不過雛形出來了。

  1. 感受到 Functional Programming 並使用它
  2. Generics

就是這兩個啦

Functional Programming

之前在看 RxSwift 文章的時候,有看到 RxSwift 可以更輕易地達成 Functional Programming 這個寫法。

要說 Functional Programming 是什麼的最簡單解釋方法,大概就是「就像函式一樣,你只要管輸入輸出,其他不要管」的感覺吧!

之前對於這個東西不是很熟悉,當然就沒有在使用它。

而開始用 RxSwift 之後,有在網路上看到別人建議比較好的寫法是:如果行為能用 Sequence 串起來,就盡量用 Sequence 串。

舉個這次我拿來嘗試的案例來說明好了。

情境:在一個畫面中,點擊一個按鈕開啟選單,選取選單的其中一項後,關掉選單、回傳選項及回到原本的畫面。

簡單的流程圖就是這樣

+-------+     +----------------------+    +----------------------+
| 按按鈕 |---> | 開啟選單畫面選中一個選項 |--->| 回傳選中的項目、關閉選單 |
+-------+ +----------------------+ +----------------------+

於是事情就變簡單了(咦,就這樣?)

有這張流程圖之後,可以發現開啟選單和回傳項目這件事情,可以透過單一個 method 觸發,回傳點選的項目可以透過 observable sequence 傳回來。

接下來只要把點擊按鈕的事件和 observable sequence 接起來,這條事件流就完成了。

看到這邊應該可以注意到用什麼 view 和 view controller 顯示這個選單根本不重要。重要的反而是,我可以執行「開選單」和拿到「選中的選項」就可以了。

能做得如此,也代表這個部分的程式碼有辦法替換掉、讓這一部分的程式碼更加可測試;進一步的更能夠在不開啟畫面的時候,用 mock 就可以模擬不同選中選項時,原本的畫面會有什麼反應。

那要怎麼把按鈕的事件流和這個開啟選單、以及回傳的流串起來呢,可以參考這樣的寫法:

// 程式碼在 RxSwift 3.x, iOS 10 SDK 下可執行
// * selectOptionPresenter 的型別會是一個 protocol ,這樣子設定的話,
// 就可以輕鬆地把它換成 mock object 了。
button.rx.tap.asObservable()
// 可以在這邊加上防止快速點擊 (.debounce 之類的)
.flatMap { _ in
// 這個地方 .present 方法會回傳一個 Observable<YourOptionTyp>()
// 這樣子在下一個 operator 就可以取得這個選中的選項了
// 接著只要在 present 的裡面實作開啟畫面等動作了
return selectOptionPresenter.present()
}
.subscribe(
onNext: { selectedOption in
debugPrint(selectedOption)
}
)
.disposed(by: disposeBag)

大概是這麼回事,用了 RxSwift 的確是可能可以比較容易注意到輸入輸出是什麼。接著再把這個觀念試著導回 Swift 原生裡面使用,應該也有辦法優化原本的程式碼。

泛型

老實說從大學上了 C/C++ 知道泛型以來,因為沒有很深刻體會的使用情境

目前因為在開發過程之中,發現太多 view controller 的行為和 view 的 layout 基本上是一模一樣,只有差在要放入資料的型別而已。

恩,這時候基本上就是要先抽象出一層 protocol ,讓這些型別可以提供一致的接口。

接著就是要處理不同物件之間傳遞,在不想寫新的類別之下,期望可以把這些型別跟著物件的傳遞傳下去。

情境也是跟上一節寫到的東西一樣,基本上就是有不同類型的 model ,會在 view model -> view controller -> presenter 之間傳遞,在需要確保傳入的資料集合(也就是備選選項)和回傳的選項一致(也就是符合期待),我就開始用了泛型。

(這應該某種程度上也算 type safe 吧,如果有錯誤請指正我)

目前為止的成果還不錯,寫出來的選單,可以用兩個不同型別的 models 使用,這兩個 models 的型別在傳入事件流和回傳的事件流中的型別都有符合各自應該有的型別,所以算是成功了!另一方面在共有的過程中,也減少了許多程式碼

小結

以上,大概有寫出自己想要的形式了(雖然真的很花時間),接著還要在歸納、系統化成 pattern 。

繼續下來想要處理的是 view controller 裡面 table view, cell 和 view model 的互動。這個部分目前還不是很滿意,還需要多調整多看看文章找找看比較好的寫法。