そのクラスは分割すべきか?
コードレビューで巨大なクラスを発見した時に、そのクラスを分割できる余地があるかコメントすることがある。その際に、そのクラスを分割するべきかどうかについての意見が一致しないことがたびたびある。
意見の対立
自分「このクラスは大きすぎる。分割した方が良い。」
相手:「このクラスは1つの責務を果たしてる。分割は不要だと思う。」
だいたいこんな感じ。
議論の焦点
この時の議論の焦点となったクラスは、データベースから一括でデータを取得し、それを加工して返すようなクラスである。このクラスは特定のデータを処理するクラスとみなせるため、1つの責務を持つクラスとも言えるという意見も確かにな〜と思っていた。
意見の食い違いの原因
最近「Good Code, Bad Code」の本を読んでいた際に、同様の問題について触れられているのを見つけた。意見の相違は、「関連する小さな問題を個別に解決するか、それらをメインの問題の本質的な一部として捉えるか」という違いからだと書かれていた。
なるほど、関連している問題を見ている観点が違っていたのか。ということと、自分も相手も「クラスは1つのことに関心を持つべき」という考え方は一致していることも本を読んでいく中で整理ができた。
どの観点からクラスを見るべきか
そのクラスがどれくらいの問題を抱えるべきか、という点は主観も入ってくるため判断が難しい。
同書では、コード品質の6つの柱を紹介している。以下の観点を考慮して、巨大なクラスがこの柱に当てはまっているか、低品質なコードを特定できるかどうかを検討すべきであると書かれている。
- コードを読みやすくする
- 想定外の事態をなくす
- 誤用しにくいコードを書く
- コードをモジュール化する
- コードを再利用、汎用化しやすくする
- テストしやすいコードを書き、適切にテストする
より良いクラスを作るためにできること
巨大なクラスの場合、1つのクラスが多くの問題を解決しようとしているため、コードの理解に時間がかかり、認知的な負担が増大する。これが自分が巨大なクラスを見たときに感じた「わかりづらさ」につながっている。
クラスの行数が多いだけで単純に分割すべきというわけでもないと思う。ただ、行数が多いクラスはそれだけ多くの問題に対処する必要があることではある。巨大なクラスを発見した場合や自分が新たに書こうとしている場合には、そのクラスが過度に多くの問題を抱えすぎていないかどうかを考慮する習慣を持っておきたいなと改めて思った。