ブログ一覧
SOLIDTypeScript設計原則

SOLID原則をTypeScriptで15分で理解する

SOLID原則は、オブジェクト指向設計の5つの基本原則です。

  • S — Single Responsibility Principle(単一責任の原則)
  • O — Open/Closed Principle(開放閉鎖原則)
  • L — Liskov Substitution Principle(リスコフの置換原則)
  • I — Interface Segregation Principle(インターフェース分離の原則)
  • D — Dependency Inversion Principle(依存性逆転の原則)

名前だけ覚えても意味がありません。なぜ重要なのかを、TypeScriptコードで見ていきましょう。

S: Single Responsibility

クラスは1つの理由でしか変更されてはいけない。

// ❌ 2つの理由で変わる
class User {
  constructor(public name: string, public email: string) {}
  save() { /* DBに保存 */ }
  sendEmail() { /* メール送信 */ }
}

// ✅ 1つの責任
class User {
  constructor(public name: string, public email: string) {}
}
class UserRepository { save(user: User) { /* ... */ } }
class UserMailer { send(user: User) { /* ... */ } }

O: Open/Closed

拡張に対して開いて、修正に対して閉じている。

// ❌ 支払い方法を追加するたびに修正が必要
class PaymentProcessor {
  pay(method: string, amount: number) {
    if (method === "credit") { /* ... */ }
    else if (method === "paypal") { /* ... */ }
    // 新方式を追加するたびにここを変更
  }
}

// ✅ 新しい支払い方法はクラスを追加するだけ
interface PaymentMethod {
  pay(amount: number): void;
}
class CreditCardPayment implements PaymentMethod { /* ... */ }
class PaypalPayment implements PaymentMethod { /* ... */ }

L: Liskov Substitution

派生クラスは基底クラスの代わりに使えなければならない。

派生クラスが基底クラスより「制約」を増やしてはいけない。例えば、Rectangleを継承したSquareで幅と高さを同時に変更すると、Rectangle前提のコードが壊れます。

I: Interface Segregation

使わないメソッドへの依存を強制するな。

1つの巨大なインターフェースより、小さく特化した複数のインターフェースの方が良い。

D: Dependency Inversion

高レベルモジュールは低レベルモジュールに依存するな。両方とも抽象に依存せよ。

// ❌ UserServiceがMySQLに直接依存
class UserService {
  private db = new MySQL();
}

// ✅ 抽象に依存
class UserService {
  constructor(private db: Database) {}
}

テストでMockを注入できる、DB変更に強い、などの恩恵があります。

CodeSenseiで体感する

SOLID原則は「読んで理解する」より「自分のコードで体感する」ほうが100倍身につきます。

CodeSenseiにあなたのクラスを見せてみてください。「このコードからSOLIDのどの原則が体感できるか」をAIが教えてくれます。


CodeSenseiを試す →

自分のコードで学んでみませんか?

CodeSenseiは無料で始められます。

無料で始める