株式会社リゾーム システム企画・開発部 第3グループの廣江(@buta_botti)です。
読書会の第2回目のレポートです。
第1回目のレポートは、こちらになります。 tech.rhizome-e.com
読書会の題材
前回に引き続き現場で役立つシステム設計の原則 〜変更を楽で安全にするオブジェクト指向の実践技法を題材としています。
2回目レポート
今回は、第2章の「変更を楽で安全にするオブジェクト指向の実践技法」で、参加者は6名でした。
それぞれの感想 + 意見交換
- if文がネストしてる箇所があるので、そこは短文にするとわかりやすくなりそう
- 大きすぎるメソッドや不必要なネストがダメというのは、RubyだとRuboCopが指摘してくれるので意識できている
- インターフェースってなんだ?(Rubyist)
- 状態遷移で列挙型が使えるというのは、なるほどなと思った
- 列挙型使ってる?
- C#で書かれてる自社製品ではほとんどみない
- TypeScriptで書かれてる自社製品では使ってる
- Rubyで列挙型というとActiveRecordのenumのイメージが強い
- 状態遷移はフラグ管理しているので、これを列挙型で管理するように直せばわかりやすくなりそう
- 列挙型使ってる?
- リファクタリングは後回しにされがち、モチベーションの維持が難しい
- 自分たちのコードがオブジェクト指向になっていくのを楽しむのがいいんじゃないかなぁ?
- 得た知見をプロダクトコードに反映して、自分のコードが本番環境に乗っていくと、徐々にプロダクトへの愛着が湧いていくはず
- 単体テストの変更を嫌がってリファクタリングに及び腰になっている
- 当然だけど、リファクタリングは継続的にし続けないといけない
- リファクタリングの価値は可読性の向上と修正をしやすくすることにある
- 経験が浅く、リファクタリングをまだ経験したことがない
個人的見解
区分オブジェクト
区分や種別で動作が変わるとき、それをif文やswitch文で書くと複雑になる。これはリファクタリングをする際にもよく聞く話で、ダックタイピングの手法を取ることで解決する。メリットとしてはそれぞれの処理が条件分岐で書かれなくなるため、コードが単純化すること。加えて、区分や種別ごとの処理がそれぞれのオブジェクトに定義されてあるため、処理の責任が明確に分かれているのもメリットだろう。
本書ではJavaのインターフェースを用いて説明されているため、静的型付けの言語としてこの手法を説明している。動的型付け言語にはダックタイピングをすることによるデメリットが存在するが、本書ではこの問題は無視されていると感じる。
個人的には動的型付き言語で闇雲にダックタイピングを使っていくのは少し危険だと感じており、動的型付け言語でダックタイピングの手法を取るのであれば、レシーバにくるオブジェクトを限定させる工夫が必要であると考えている。本書ではJavaの列挙型を用いて、クラスの一覧を記述することでさらに簡単になると説明しているが、これ相当のことが動的型付け言語においては必須レベルだろう。
状態遷移を列挙型で管理する
興味深かったのはこの状態遷移を列挙型で管理するという話だ。今関わっているアプリケーションでは状態遷移をもっぱらフラグで管理している。最近ではActiveRecordのenumを使ったりしているが、それはどちらかというとデータベースの列挙型のことであり、ここのでの列挙型というのはそういったものではない。
例えば、現在の状態だけを持っていても、その状態の遷移に関わるルールは複雑なコードになっている場合がある。ここでの「列挙型で管理」というのはこの「状態遷移のルール」を列挙型で管理するというものである。つまり、遷移元の状態から遷移可能な状態を列挙型で所持している。
Rubyでは明確な列挙型は存在しないが、その手法は真似できると思っていて、例えばHashを使って遷移元のキーと遷移可能先の値を持つことができる。レコードのカラムから現在の状態を取得し、ハッキュのキーから現在の状態で遷移可能な状態を取得し、イベントに従って状態を遷移させる。この時、発生し得るイベントの一覧は値にもつ遷移可能な状態から推測することができ、そのイベントが正当なものかどうかは、遷移先の状態が値に含まれているかどうかで判別できる。
状態遷移図の代わりにもなり、コードを読む際の負担も減ると思うので、是非とも取り入れていきたい手法だと感じた。
まとめ
読書会を通して得た知見を、自分たちのプロジェクトに具体的に当てはめて考えたり、Rubyでは存在しないインターフェースという概念を知るきっかけにもなり、言語の垣根を超えた有意義な意見交換ができました。また、問題点は認識しつつも、実際にそれの改善に着手するのにはやや及び腰である点が浮き彫りになり、今後の課題が出てきました。
読書会はベテランがさらに知識を深めるのはもちろんですが、経験の浅い人が本の内容に沿うことで、わからないことを質問しやすくしている*1なとも思うので、とても有意義な時間だと感じています。今後参加者が増えたり、今の本を読み終えても継続的に読書会を続けていけるといいなと思います。
*1:わからないことがわかるので質問が明確になる