まとめ — 実務でクラス設計を判断するために
第1章のgod classから始まり、第13章のリファクタリング実践まで、13章分の判断基準を積み上げてきました。 実際のコードに向き合うとき、13章分の内容を最初から思い出す必要はありません。 この章では、判断に迷ったときに立ち返れるよう、ここまでの内容をチェックリストの形に整理します。
第1部が積み上げてきたもの
第1部(第1〜7章)は、フレームワークに依存しないクラス設計の原則を扱いました。 god class(第1章)から始まり、カプセル化とtell-don't-ask(第3章)、単一責任の原則によるクラスの分割(第4章)、継承とコンポジションの使い分け(第5章)、インターフェースを介した抽象への依存(第6章)と、判断基準を1つずつ積み上げました。
第7章は、この積み上げを凝集度と結合度という1つの物差しに統合しました。 単一責任の原則は凝集度を高く保つための手段であり、依存性逆転・開放閉鎖・インターフェース分離の各原則は結合度を低く保つための手段です。 リスコフの置換原則は、その結合度を下げる工夫が成り立つための前提条件として位置づけられます。
第2部が積み上げてきたもの
第2部の応用パート(第8〜13章)では、ここまでの原則をLaravelの実務コードに応用しました。 Fat Controller・Fat Modelの診断(第8章)から始まり、Eloquentモデルの責務(第9章)、サービスクラスへの切り出し(第10章)、Laravelのコンテナを使った依存性注入(第11章)、Form Requestとカスタム例外による設計(第12章)と判断基準を重ねました。 第13章では、その全部を1つのControllerに通しで適用しました。
第13章の冒頭で述べたとおり、この過程で新しい判断基準は登場していません。 ここまでの13章で見た基準を、順番に適用しただけです。
実務で使うためのチェックリスト
自分の書いたクラスやレビュー中のコードを前にして、次の問いに順番に当てはめてみてください。 該当する項目があれば、それが次に手を入れる場所です。
クラス単体を見るとき
- そのクラスが変更される理由は、1つに絞れるか(第4章)
- publicなプロパティを外部から直接書き換えられる状態になっていないか(第3章)
- 呼び出し側がそのクラスの内部状態を覗いて、判断や計算をしていないか(第3章)
クラス同士の関係を見るとき
- 継承の軸が複数になっていないか。増えるほど組み合わせが増えていないか(第5章)
- 具象クラスに直接依存していて、実装を差し替えるだけで依存元まで書き換える必要が生じていないか(第6章)
- 条件分岐を、既存コードの修正でなく実装の追加で解決できているか(第7章)
- 派生クラスが、基底クラスの期待する振る舞いを裏切っていないか(第7章)
- 使わないメソッドへの依存を、インターフェースを通じて強制していないか(第7章)
Laravelでの実装を見るとき
- Eloquentモデルに書かれている処理は、そのモデル自身のデータの表現・解釈だけで完結しているか(第9章)
- Controllerに、複数の関心事を調整する処理が残っていないか(第10章)
- サービスクラスへ切り出した後も、単一責任は保てているか。ファイルを分けただけになっていないか(第10章)
- インターフェースへの依存を、Laravelのコンテナで解決できているか。
bind()の登録漏れがないか(第11章) - リクエストの形式チェックはForm Requestへ、意図を伝える例外はカスタム例外クラスへ切り出せているか(第12章)
次に読む
本ガイドは、クラス設計そのものの範囲にとどめてきました。 DDD戦術パターン(値オブジェクト・エンティティ・集約・リポジトリパターン)や、クリーンアーキテクチャの層実装(ユースケース層・プレゼンテーション層・トランザクション境界の管理)は、範囲の外に置いています。
- Laravel × DDD × クリーンアーキテクチャ実践入門 — 本ガイドで扱わなかったDDD・クリーンアーキテクチャの実践編です
- クリーンコード入門 — クラス — TypeScriptでのクラス設計を扱います。言語は異なりますが、原則の多くは共通しています
- クリーンコード入門 — SOLID原則 — 第7章で扱ったSOLID原則を、TypeScriptの例で振り返る内容です