「オブジェクト指向設計実践ガイド」がすごくよかった

普段RailsでWebアプリを作っていて、いつクラスを作るべきか、どんなインターフェイスを作るべきか、そもそもよい設計やコードとは何なのかよくわからなくなっていた。

同僚に相談したらこの本を勧められて2017年に1回途中まで、年明けにもう1回全部通して読み直したのでいったんまとめる。

この本を読んでなおいろんな機能が詰まりまくったServiceクラスを作るPullRequestを出した自分に
丁寧にapp/models以下に単一責任の原則に基づいたプレーンなクラスを作って、ドメインモデルを表現するコードレビューをしてくれた同僚がいた。

ちょうどそのレビューの最中に教えてもらった記事がある。

qiita.com

この記事に出てくるダメServiceクラスみたいなものを本当に作りかけていて危機感を覚えたし、具体的な問題意識を持って本を読み直すきっかけになった。

いまその時とは違う職場で働いているが、当時のコードレビューや本、記事で言われている内容がかなり役立っている。

新しい環境でコードを読みながらキャッチアップする機会が多く再認識したことがあって
今までapp/models以下にActiveRecordを継承したモデルクラスだけが存在し、そのサービスのドメインロジックはそれっぽい名前のServiceクラスに手続き的な処理の羅列として閉じ込めるような書き方がされているコードをよく見た気がするし自分でもめっちゃ書いてた記憶がある。

こういうクラスがある場合に新しい環境でコードを読み始めてつらいと思ったのが、そのクラスがいったい何の責任を持ったクラスなのかわからなかったり、staticな呼び出しをされまくる便利クラスになっていて変更のためのコストが異常に高かったりすること。

たくさんの引数を渡してその内容によって処理の分岐をするif文の羅列、それに伴って膨らむrspecのcontextブロック
ロジックが詰め込まれていてしかもstaticに呼び出されたりすると、処理の内容を変更しようもんなら影響範囲がどこまで及ぶのか関数名でgrepして確認をしないといけない。(grepすれば調べられる分まだマシかも)

この本を読んでそういうコードを生まないためにどう対処するべきか、少しずつクリアに見えるようになり始めた。

特に役立ったと感じるのは

  • 2.2 単一の責任を持つクラスをつくる
  • 3.2 疎結合なコードを書く
  • 4.3 パブリックインターフェースを見つける -> 「どのように」を伝えるのではなく「何を」を頼む
  • 4.5 デルメルの法則
  • 5 ダックタイピングでコストを削減する

のあたり。

オブジェクトが「メッセージ」を送っている。という話がRubysendメソッドと自分の中で結びついて気持ちよかったり
単一責任の話や、ダックタイプの話が直接先述のServiceクラスをリファクタするヒントになっていたりして
「明日、あのコードをどう直すか」というスピード感で自分の指針になったことにはとても感動した。

しかもありがたいことに今の職場でもこの本がデスクに置かれている同僚がいて、設計の相談が来た時にちょうどこの本に載っているような問題に遭遇して「あのパターンが使えるね」って話しながら設計に落とし込めたりする体験もできた。

ただ単にこの本を読んだ自分の考えを押し付けるわけでもなく「なぜそう思うか」を具体的に言語化した上でレビューしたり、共通の認識を持った上でお互いに納得いく設計にできたりしているので、当初思っていたよりもかなり読む価値のある本になっていた。ラッキー。

ドメイン駆動設計あたりが自分の中でホットなので冷めないうちに次はこの本を読んでみようと思う。