0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

リスコフの置換原則(LSP)におけるOOPとFPの比較

Last updated at Posted at 2025-04-21

リスコフの置換原則(LSP: Liskov Substitution Principle)は、「派生クラスは基底クラスと置き換えてもプログラムの正しさが保たれるべきである」という設計原則です。OOPでは継承の安全性が問われるのに対し、関数型では型の整合性と構造の一貫性に注目が集まります

リスコフの置換原則についての詳しくはこちらで

OOPにおけるLSPの実装例

interface Flyer {
  fly(): void;
}

class Bird {
  // 共通の鳥の性質(例: 鳴くなど)
}

class Sparrow extends Bird implements Flyer {
  fly(): void {
    console.log('スズメが飛んだ');
  }
}

class Penguin extends Bird {
  // fly() は実装しない
}
function makeFly(flyer: Flyer): void {
  flyer.fly();
}

const sparrow = new Sparrow();
makeFly(sparrow); // ✅ OK

const penguin = new Penguin();
// makeFly(penguin); // ❌ コンパイルエラー(型不一致)

このようにすれば、Flyer 型に対してのみ fly() を呼び出せるようになるため、置き換え可能な設計=リスコフの置換原則に準拠した設計になります。

FPにおけるLSPの実装例

関数型では「型ごとの明確な分離」と「構造の保証」により、LSP違反を事前に防ぎやすくなっています。

type Bird = { kind: 'bird'; fly: () => string };
type Ostrich = { kind: 'ostrich' };

type Animal = Bird | Ostrich;

const isBird = (a: Animal): a is Bird => a.kind === 'bird';

const makeFly = (animal: Animal): string =>
  isBird(animal) ? animal.fly() : 'I cannot fly';
  • 明示的に Ostrich の飛行不能を表現することで、「安全に置換できる前提」を避けている。
  • ユニオン型とパターンマッチにより、型の置換が意味的にも安全。

比較まとめ

観点 OOP FP
抽象化手段 継承とインターフェース ユニオン型・タグ付き構造
LSP違反の危険 実行時に現れる 型で表現され防止しやすい
置換の安全性 意図しないオーバーライドに注意 明示的な分岐で安全な選択
テスト性 モックによる検証が必要 型の分離により検証容易

継承や共通インターフェースを使うOOPでは、意味的な一致まで注意が必要です。関数型では構造的に明示することで、LSPのリスクを低減できます。

次回は「インターフェース分離の原則(ISP)におけるOOPとFPの比較」についてです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?