最近、お仕事でリファクタリングをやっていて、やっと落ち着いてきた。
最近の潮流を取り入れてCleanArchitectureの雰囲気の中でRxJavaを使ってみた。
参考にしたのはこんな記事やリポジトリたち。
参照はできないけど隣に座っている方のコードもかなり参考にさせていただいた。(頭が上がらない)
- https://github.com/android10/Android-CleanArchitecture
- http://tomoima525.hatenablog.com/entry/2015/08/13/190731
- http://konifar.hatenablog.com/entry/2015/04/17/010606
それで、昨年末あたりに手を動かすためにapproomに適用してみていた。
がこれはホントに申し訳ないがめっちゃ中途半端な状態である。(最後のコミットが[wip] w
が、上の記事の日付からも分かる通り、2016年時点で割りとデファクトになりつつある手法であるので、基本的には豊富な記事とStackOverflowに助けられてリリースにこぎつけられそうな状態までもってこられた。
現状はData、Domain層の構築とPresentation層へのつなぎ込みまでができていて、Presentation層は実際は既存の構成ほぼそのままな状態。
Presentation層もきちんと作れればActivityのライフサイクルから切り離された純粋なViewのテストが容易になるので、少しづつ移行していきたいところ。
良かった点
そんなわけで良かった点は
- Domain層が出来たおかげでデータ処理をActivityから切り離すことができた。
- 例えば、この画面は追加でキャッシュを効かせるようにしたい、と言った変更を行う際に画面側に手を加える必要がなくなった。
- UIの状態から切り離されたのでさくっとテストが書けるようになって、実際ずいぶんテストコードを増やすことができた。
- 並列処理にRxJavaを使うことでデータの流れが簡潔になった。
- 入れ子のAsyncTaskでActivityのメンバ変数にアクセスしてあれこれみたいな辛いコードが一掃された。
- これはデグレの危険もあったけど、可読性が上がったのと前述のテストコードが増えたのとエラーハンドリングの改善で、メリットのほうが大きかったと思っている。
辛かった点
逆に辛かった点ももちろんあって
- よくRxJavaは学習コストが高いと言われるけど、これは本当にそうで未だに膨大な情報と機能を全部把握できているとは言い難い。
- 手を動かして事前に検証していたものの全然足りず、前半のコードを後半一部書き直したりしていた。
- RxJavaと一口に言っているけどタイミング的にギリギリ採用したのがRxJava1系でメインストリームは2系に移っていくので、移行も考えないといけない。
- でもまだ移行の必然性と言うまでは高まっていないので様子見。多分個人では今後2系を使うだろう。
- このぎょーむをしている間、ひたすらIDEとUnitTestの結果を眺める日々だったので、ちょっとつらかった。
- それで気晴らしに息子用のアプリを書いた。(https://github.com/ymegane/TapTapTap
RxJavaのエラーハンドリング
ところで、RxJavaのエラーハンドリングが一番つらかった。
最終的にはテストコードで動きを確認して肌で覚えていったけど、どういう時は最後のObserverまでエラーが到達するのか、到達せずにExceptionが起きてしまうのか、最初は本当に良くわからなかった。
参照していたのは以下の記事たち。今読むと、分かる。
- Error Handling · ReactiveX/RxJava Wiki · GitHub
- RxJava:Error Handling Operatorを使ったエラーハンドリング方法を理解する – techium
Error handling in RxJava
当時のメモ(つらそう
- toListする前にExceptionがおきると受け取る人がいないので落ちる
- single, firstは、Observable.emptyを返した時は対応できない。
- singleOrDefaultなどdefaultValueを定義することで対応できる。
- Observable.createは予期しないExceptionに対応できないので、できるだけ使わない
そんな訳で、もうすぐこの改善が入ったアプリがリリースできそう。
たぶんパフォーマンスも上がっているはず。