第01回: SOLID原則 — 読み解き編 — 「良いコード」って、本当に定義できますか?

章: 第1章: オブジェクト指向の深化

「修正するたびに別の場所が壊れる」——その原因を特定できていますか?

「このコード、手を入れるたびに予期しない場所が壊れる」——チームで共有した経験ではないでしょうか。

原因のほとんどは、クラスが複数の責務を抱え込んでいるか、依存関係が複雑に絡み合っていることにあります。

SOLID原則は、そうした「変更に弱いコード」を避けるための5つの指針です。一度身につけると、設計の判断が格段に速くなります。

SOLID原則とは何か

SOLID原則は「変更に強いコード」を書くための5つの指針です。それぞれの頭文字をまとめた名称で、オブジェクト指向設計の出発点として世界中で使われています。

原則 名称 一言で言うと
S 単一責務の原則 1クラスは1つの理由でのみ変更される
O 開放閉鎖の原則 拡張には開いて、修正には閉じる
L リスコフ置換の原則 親クラスを子クラスで安全に置き換えられる
I インターフェイス分離の原則 使わないメソッドに依存させない
D 依存性逆転の原則 抽象に依存し、具体に依存しない

チェックポイント: 「このクラスを修正する理由が2つ以上ある」と感じたら、Sの原則(単一責務)が崩れているサインです。

悪い例 vs 良い例:Sの原則(単一責務)


<?php
// NG: 請求書クラスが「書式化」と「保存」を両方担っている
class Invoice {
    public function format(): string { /* ... */ }
    public function save(): void { /* DBに保存 */ }
}

// OK: 責務ごとに分離する
class InvoiceFormatter {
    public function format(Invoice $inv): string {
        return $inv->id . ': ' . $inv->total;
    }
}
class InvoiceSaver {
    public function save(Invoice $inv): void {
        // DB保存処理
    }
}

SOLID違反が引き起こすコスト比較

観点 SOLID違反のコード SOLID準拠のコード
修正の影響範囲 1箇所変えると別の責務まで影響 変更箇所が1クラスに限定される
テストのしやすさ DBや外部依存がテストに混入する 単独で単体テストできる
再利用性 不要なロジックがセットでついてくる 必要な部品だけ使える
拡張コスト 機能追加のたびに既存コードを変更 新クラスの追加で対応できる

チェックポイント: 「このクラスのテストを書くとき、DBのモックが必要になる理由は何か?」と自問すると、責務の混在に気づきやすくなります。

なぜ今SOLID原則を学ぶのか

規模が小さいうちはSOLID違反は気になりません。しかしクラスが増えるほど、違反はバグと修正コストに直結します。

  • 責務が混在したクラスは、変更のたびに副作用が起きやすい
  • 具体実装への依存は、テストで差し替えが効かなくなる
  • 拡張に修正が必要な設計は、新機能追加のたびに既存コードが壊れるリスクがある

SOLID原則を早い段階で身につけると、「このクラス、後で修正が怖い」という感覚が消えていきます。

チェックポイント: 「責務の境界を先に決める」「依存の向きを確認する」「差し替えテストを行う」の3ステップが設計見直しの出発点です。

まとめ & 次のステップ

  • SOLID原則は「変更に強いコード」を設計するための5つの指針
  • Sの原則(単一責務)は「このクラスが変わる理由は1つだけか」を問うこと
  • クラスが増えるほどSOLID違反の修正コストは膨らむため、設計段階で意識する価値がある
  • 「テストが書きにくい」「修正が怖い」という感覚はSOLID違反のサインとして活用できる

次回はSOLID原則の実践編として、O(開放閉鎖の原則)を中心に「既存コードを変えずに機能を追加する」設計を手を動かして学びます。

Related Articles