ホーム › オブジェクト指向設計(OOP) › OOP-02
OOP-02: SOLID 原則の実例
SOLID 原則は、保守しやすく変更に強いオブジェクト指向設計のための5つのガイドラインです。 ここでは特に実装が明確な「S(単一責任)」「O(開放閉鎖)」「D(依存性逆転)」の3つを Java コードで解説します。
SOLID 原則とは
SOLID は以下の5原則の頭文字を取ったものです。コードが大きくなるほど、これらの原則に従うことで変更コストを抑えられます。
S — 単一責任原則(Single Responsibility Principle)
クラスが変更される理由は1つだけにします。複数の責任を1つのクラスに持たせると、1か所の変更が別の機能に影響を与えるリスクが高まります。
O — 開放閉鎖原則(Open/Closed Principle)
クラスは「拡張に対して開いており、変更に対して閉じている」べきです。新機能を追加するとき、既存のコードを変更せずに新しいクラスを追加するだけで対応できる設計を目指します。
D — 依存性逆転原則(Dependency Inversion Principle)
上位モジュールは下位モジュールに依存してはなりません。どちらも「抽象(インターフェース)」に依存するべきです。これにより、依存先の実装をテスト用のモックに差し替えることが容易になります。
サンプルコード
Java 8 では Strategy パターンの実装にクラスを都度定義する必要があります。DiscountStrategy はインターフェースが1メソッドしか持たないため、Java 8 以降はラムダ式で簡潔に書けます。
よくあるミス・注意点
⚠️ God クラス(何でも一つのクラスにまとめる)
すべての処理を1つのクラスに書いてしまう「God クラス」は、単一責任原則の典型的な違反です。 最初は便利に見えても、クラスが大きくなると変更のたびに別の機能に影響が出やすくなります。 「注文データの管理」「DB 保存」「メール送信」のように責任を分離し、それぞれを独立したクラスに任せましょう。
⚠️ 具体クラスへの直接依存でテスト困難
BadOrderService のように、new MySqlOrderRepository() を直接フィールドに持つと、 テスト時に DB なしで動かすことができません。 インターフェースを介してコンストラクタで渡すコンストラクタ注入を使うと、テスト時にモックを渡せるようになります。 これが依存性逆転原則(D 原則)の実践的な恩恵です。
テストする観点
GoodOrderServiceにモックの Repository を注入して、実際の DB なしでテストできること(D 原則の恩恵)- 新しい割引タイプ(例: VIP 割引)を追加するとき、
DiscountCalculatorを変更しなくてよいこと(O 原則の確認) OrderRepositoryとOrderNotificationが独立してテストできること(S 原則の確認)- 各割引率(学生 20% OFF、会員 10% OFF)が正しく計算されること(境界値: 価格 0 の場合も確認)