リスコフの置換原則
バッドプラクティスから学ぶ リスコフの置換原則 による柔軟なシステム設計
リスコフの置換原則 とは?
リスコフの置換原則 (Liskov Substitution Principle, 略称LSP) は、オブジェクト指向設計の原則の一つであり、次のように説明できます。
「派生クラスは常にその基底クラスと置き換え可能でなければならない。」
つまり、サブクラスはスーパークラスの振る舞いや期待を壊さずに代替可能であるべきであり、サブクラスがスーパークラスの動作を変更したり、矛盾する動きをしてはいけないという原則です。
なぜ リスコフの置換原則 が重要なのか?
この原則が守られていないと、ポリモーフィズムの利点が損なわれ、コードの柔軟性が失われます。リスコフの置換原則を守ることで、クラスやオブジェクトが互換性を持ち、コードの再利用性が向上し、変更に強い柔軟な設計が可能になります。
解説
以下、具体的なコード例を通じて、実際にどのような問題が起こり、リスコフの置換原則を守ることでそれがどのように解決されるのかを見ていきましょう。
修正前のコード
例えば、次のようなコードを考えてみましょう。
問題点
上記のコードでは、Square
クラスはRectangle
を継承していますが、挙動が異なります。Square
は幅と高さが常に同じですが、resize_and_calculate_area
メソッドは長方形を前提にしているため、正方形の場合は予期しない結果が起こります。これはリスコフの置換原則に違反している典型的な例です。
修正後のコード
リスコフの置換原則に従えば、正方形と長方形を互換性がある形で設計するには、共通のインターフェースを持たせ、継承ではなくポリモーフィズムを利用します。
解決された問題
修正後のコードでは、Square
はRectangle
の振る舞いを壊すことなく、共通の親クラスShape
を経由してポリモーフィズムを活用しています。これにより、各クラスが持つ固有の特性を維持したまま、互換性を保つことができ、予期しない結果がなくなりました。
まとめ
リスコフの置換原則を守ることで、オブジェクト指向設計における継承の誤用を防ぎ、変更に強く柔軟で信頼性のあるシステムを構築できます。継承よりインターフェースや抽象クラスを使ったポリモーフィズムを適切に利用することで、よりエレガントな解決策が可能となります。
練習問題 (1)
以下のコードは、リスコフの置換原則に違反しています。修正してください。
修正前のコード
修正後のコード
解説
修正前のコードでは、ペンギンが予期しない例外を発生させ、基底クラスであるBirdの振る舞いを破壊していました。修正後は、共通のメソッド名を用いて各クラスが適切な動作をするようになり、リスコフの置換原則が守られています。
練習問題 (2)
以下のコードはLSPに違反しています。問題を修正しましょう。
修正前のコード
修正後のコード
解説
修正前はサブクラスが基底クラスの振る舞いを破壊し、LSPに違反していました。修正後は、支払い機能を持つかどうかの判定メソッドを共通化し、適切な動作を行うようにポリモーフィズムを活用しています。これにより、基底クラスの振る舞いを壊さずにリスコフの置換原則が守られています。