📄
概念 📚 software-design-concepts

設計原則

SOLID・DRY・KISS・YAGNIなどコード品質を支える設計原則とその実務での適用

設計原則とは、長年の実践から導き出されたソフトウェア設計の指針群であり、変更に強く・読みやすく・テストしやすいコードを生み出すための共通言語として機能する。特定の言語やフレームワークに依存しないため、チームの設計議論においてもレビューコメントの根拠としても広く使われる。

SOLID原則はRobert C. Martinが整理した5つの原則の頭文字を取ったものだ。Single Responsibility Principle(単一責任)はクラスや関数が変更される理由を一つに絞る。Open/Closed Principle(開放閉鎖)は拡張に対して開き・修正に対して閉じる。Liskov Substitution Principle(リスコフ置換)はサブタイプが基底型を置換できることを保証する。Interface Segregation Principle(インターフェース分離)は使わないメソッドへの依存を避ける。Dependency Inversion Principle(依存性逆転)は具象ではなく抽象に依存する。

DRYは「同じ知識を二箇所に書かない」という原則だが、単なるコードの重複排除と混同しないことが重要だ。偶発的な類似コードをまとめることで却って結合度が増すケースもある。WET(Write Everything Twice)やAHA(Avoid Hasty Abstractions)はDRYの過度な適用への反省として生まれた。KISSは不必要な複雑さを避け、YAGNIは現時点で必要のない機能を実装しないことを求める。凝集度(Cohesion)を高め結合度(Coupling)を下げることがモジュール設計の基本であり、Tell, Don’t Ask原則はオブジェクトに判断を委ねることで手続き的なゲッター列挙を避ける。

コードレビューで着目するポイント

  • クラスや関数が複数の変更理由を持っていないか(SRP違反)
  • 新しいふるまいを追加するためにswitch文や条件分岐を修正しているか(OCP違反の兆候)
  • サブクラスが基底クラスの事前条件を強めていないか・事後条件を弱めていないか(LSP違反)
  • 使われないメソッドをインターフェースが含んでいないか(ISP違反)
  • 具象クラスを直接new()している箇所でDIが使えないか(DIP違反)
  • コピー&ペーストされたロジックに同じ「知識」が重複していないか(DRY違反)
  • まだ使われていない汎用化・拡張ポイントが実装されていないか(YAGNI違反)
  • オブジェクトの状態を外部から取得して外部で判断していないか(Tell, Don’t Ask違反)

典型的なアンチパターン

God Class(神クラス): 1つのクラスがデータアクセス・ビジネスロジック・バリデーション・フォーマットをすべて担う。変更のたびにクラス全体を読み直す必要が生じ、テストも肥大化する。

Premature Abstraction(時期尚早な抽象化): 用途が1つしかないうちにインターフェースを切り、FactoryやStrategyを導入する。DRY適用の名のもとにAHAが警告するパターンそのものであり、将来の変更時に抽象が足かせになる。

Shotgun Surgery(散弾銃的変更): 一つの機能変更が多数のファイルに及ぶ。凝集度が低く結合度が高い設計で発生し、変更漏れによるバグのリスクが高い。

参考リソース

  • Robert C. Martin『Clean Architecture』(ドワンゴ、2018)
  • Robert C. Martin『Agile Software Development, Principles, Patterns, and Practices』(Pearson、2002)
  • Martin Fowler「AHA Programming」 — https://kentcdodds.com/blog/aha-programming
  • Sandi Metz『99 Bottles of OOP』— Tell, Don’t Ask の実践例が豊富
  • SOLID原則の詳解:Uncle Bob公式ブログ https://blog.cleancoder.com