なるようになるかも

力は多くの場合、その人の思いを超えない。

RxSwift の実装例っていろいろありすぎて困るよねって話。

元ネタ

感想

他人のコードを読むとき、どういうフレームワークや言語でも、「この機能をこんな使い方するのか……マジかよ……」というのはいい意味でも悪い意味でもあると思うのですが(悪い意味の方が7割くらい)、Rx 関連になるとみんな実装方法がまちまちで、もはや何を参考にしていいのか分からない状態になりますよね。

RxSwift 界隈と RxJava 界隈とでも空気感が全然違ったりしますし。

個人的な考えとして、Rx + MVVM を独学で学ぶならば、習熟段階に応じて、

  1. BehaviorRelay を入れ物にして、PublishSubject でイベントを発火する似非 Rx で考え方に慣れる
  2. 副作用(状態)を減らすことを腐心し、関数指向を目指しつつ、いろいろ妥協もして動くものを作る
  3. 理想的な Rx + MVVM アーキテクチャに到達する(自分はしてない)

と進んでいくのが無難だと思っていて、元記事はサンプルコードの一部の「そもそも Swift としてどーなの?」っていう突っ込みポイントを除けば、「入門者への記事」としては、そこまで悪いとも思わなかったり。

Rx 全然分からない人に向けて、挫折しにくい、自分の書いたコードと動作がわかりやすく対応付くような、「最初の一歩を踏み出させるサンプルコード」を作成するのって、なかなかハードルの高いタスクだと思うんですよね。

私的な実装例

なんとなく自分も実装してみたり。とはいえ、おおよその実装は前述した記事のコードをパクった真似た上に、テストコードはないのですが……。(あとで書いた)

github.com

ViewModel の作り方だけは、わりと変えてます。

ViewModel を作るときに、「依存モジュール」「入力」「出力」がごっちゃにならないように、こういうプロトコルに準拠させてます。

protocol ViewModelType {
    associatedtype Dependency
    associatedtype Input
    associatedtype Output
    
    init(_ dependency: Dependency)
    
    func transform(_ input: Input) -> Output
}

イニシャライザで受け取るのは依存するモジュールだけにして、入力の Observable<T> を受け取り、出力の Driver<T> を返す transform() というメソッドを用意してます。ViewModel のコード全体はこちら

この手法、すっきりしていてわたしが私的にコードを書くときには好んで使うのですが、ものすごい複雑なケースだと破綻するっぽい?

記事のレベルと共感

以下、あんまり関係ない余談。

某ポエムサイトでは「エンジニアは全員記事を書くべき」「ゴミ記事で汚染するべきではない」みたいな論争をやってるっぽいですね。

わたしがプログラミングの記事を書いているのは、自身が初学者だったときにいろいろな記事にお世話になった恩返しをしたい……というのが動機としてあったりしました。

そうした頃に読んだ記事は、片っ端からブックマークに入れていて、今でもたまに読み返しているのですが、

  • この実装よりももっといい方法があるなー
  • なんでこんなことで悩んでいたんだろう?
  • 当時は理解できなかったけれど、こういうことだったのかー
  • まだ難しくて読めない……

みたいに、自身に知識に応じて内容の理解度が変わって、新しい発見があって面白いです。

私見として、高度で正しい技術記事だけがこの世にあるよりも、間違ったり迷走したりしてるような記事も含めて、玉石混合の記事がある方が良いと思っています。

というのも、記事への共感というか、理解しやすさというのは、読み手と書き手のレベルが最接近しているときが最大になるという体感があって、中級者以上の人にとってはどうでもいいような悩みやトラブルの記事もきっとどこかの誰かの役に立つし、逆に「いいね」がまったく付かない内部実装について詳述したようなマニアックな記事もどこかの誰かにとっては最高の読み物になると信仰してます。

なので、明確な誤りに対する指摘は有益だと思いますが、「このやり方が正しい」という押し付けについてはあまりしたくはないんだけど、コードレビューをお仕事でしてるとそれに近いことをやってしまうことがあって、なかなか難しい……。