オブジェクト指向な人がrx swiftを試してみた

Post on 09-Jan-2017

1.307 Views

Category:

Engineering

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

オブジェクト指向な人が

RxSwift を試してみた

Twitter アカウント: grachro

2000 年初頭から、だいたいずっと Java2014 年Oisix iPhone アプリ立ち上げで設計とプログラミングを担当

2016 年 最近は Python とか Kotlin の開発もやってます

自己紹介

ReactiveSwiftReactiveCocoa

RxSwiftRxCocoa

PromiseKit ReactKitSwiftTask

今回関数型のプログラム用のライブラリをいくつか調べてみて、個人的にRxSwift が一番しっくり来たので試してみました。

目次

RxSwift がしっくりきた理由 3 つ

書いてみた

デザインパターンのオブザーバーパターンで理解が可能

RxSwift がしっくりきた理由 その 1

http://reactivex.io/documentation/observable.htmlComposition via Observable Operators

Observables and observers are only the start of ReactiveX.

By themselves they’d be nothing more than a slight extension of the standard

observer pattern, better suited to handling a sequence of events rather than a single callback. 公式サイトでは、

超訳ですが、

「 Observables と Observersを起点とした、スタンダードなオブザーバーパターンの拡張」と紹介がされています。

観察する人

Observer Subject観察対象

ここでオブザーバーパターンを復習すと、

notify

観察対象のオブジェクトの変化を観察者のオブジェクトが観察するというパターンでした。

観察する人

Observer Observable

観察対象

ReactiveX だと、

subscrive

観察対象は Observable と呼ばれ、観察者は Observar となります。Observable から値 (element) がObserver へどんどん流れてくる設計になってます。用語は異なるところがありますが、だいたい同じ構造と理解しました。

RxSwift がしっくりきた理由 その2

メソッドチェーンでかける

RxSwift のコード例。RxSwift では観察対象が返すオブジェクトを観察部分がメソッドチェーン形式で変更していきます。

Observable 観察対象

Observer

観察部分

いっけんすると10 年以上前にはやった、「流れるようなインターフェース」(命名、マーティンファウラー先生)ぽいのでオブジェクト指向な人でも関数型プログラムの敷居が半減します。

実際はメソッドチェーン中に型が変わっていくので、それほど単純ではありません。

またこの形式は関数型のライブラリでよく見られる形なので、特に RxSwift 固有の特性というわけではありません。

RxSwift がしっくりきた理由 その3

マーブル図でUML だと難しいタイムラインがわかりやすくなる

観察対象

観察者 1

観察者 2

マーブル図の例です。右向きの矢印が時間の流れを表していて、上下のラインが観察対象と観察者の関係を表しています。

RxSwift のドキュメントはマーブル図を使って説明されています。このダイアグラムで UML だと表現しにくかった時間の経過がシンプルに表現できるようになります。

以上をふまえて実際に使いたいシチュエーションを想定してRxSwift を試してみました。

タップしたらすぐに時間がかかるネットワーク処理を実行

ボタンは連続タップできる

ネットワーク処理は直列で実行その間タップされた情報はキャッシュして次のタイミングでまとめて送信

終わったら順次、処理結果を表示

想定シチュエーション

3 2 1

ネットワーク処理

3 2 1

バッファ

《 1》

今回この処理をRxSwift でどうなるかを試行錯誤しました。マーブル図で書くとこうなります。

1 つめの観察対象

と観察者

2 つめの観察対象

と観察者

PublishSubject

Obserbver

Obserbver

PublishSubject

観察対象と観察者のペアを2 つ連続させています

3 2 1

ネットワーク処理

3 2 1

バッファ

《 1》

3 2 1

ネットワーク処理

3 2 1

バッファ

《 1》

最初にタップされた情報をObservable の一種のPublishSubject に順次追加していきます。

1

3 2 1

UIButton をタップしたら、

数値を Suject に追加 (onNext) します。

rx_tap は RxCocoa の機能です。RxCocoa は RxSwift と同時に使えるライブラリで、 UIKit のクラスで RxSwift を使えるようにる。

1 つ目の観察物に 追加された情報は

1 つ目の観察者に順次送られていきます。

3 2 1

ネットワーク処理

3 2 1

バッファ

《 1》

実際のコードがこちら

最初の ovserveOn で以降の処理をバックグラウンドで実行するようにします。

これで連続タップができるようになります。

3 2 1

ネットワーク処理

3 2 1

バッファ

_queue:Subject

次の 2 行で前のネットワーク処理を待っている間に溜まった情報をバッファさせています。

buffer を使うと溜まった値は配列で送られるようになりまが、一定間隔で空配列も送られてくるのでfilter しています。

3 2 1

buffer

filter

3 2 1

3 2 1

ネットワーク処理

3 2 1

_serverResult:Subject

次の flatMap でネットワーク処理をします。

《 1》

ネットワーク部分は詳細は省略します。非同期を直列にする処理は RxSwift だとやり方が見つけられなかったので基本ライブラリでとめます。

サーバ処理結果は新しい Obsarvable にくるまれて、次の観察値として渡されます。

ネットワーク処理

3 2 1ネットワーク処理の結果を 2 つめの観察対象に追加して、1 つめの観察処理は終了。《 1

3 2 1

ネットワーク処理

3 2 1

バッファ

《 1》

2 つ目の観察対象がネットワーク処理結果を返すようになります

最後に 2 つめの観察者(ここでは UILabel )が観察して、観察値をラベルに表示。ここでも RxCocoa の bindTo を使います。

《 1》《 2⚡ 3 》

今回やってみた感想

正しいコードかはともかく RxSwift を使うと非同期処理を使うコードがかなりシンプルにかけた。

エラー処理を入れるとどうなるかは課題。

とわ言え、ライブラリの全体像を把握するのは時間がかかり、サンプルコード以上のことをやる敷居は高かった。

ご清聴ありがとうございました

今回のコードは github にあげてます https://github.com/grachro/RxSwiftSample

top related