generated at
リスコフの置換原則 (LSP)
Liskov Substitution Principle, LSP
SOLID L
元は、継承を使用できる条件の指針を提供する原則
基底型(親)から派生型(子)に置換可能であるときにのみ、継承関係を与えるべき、というもの
「Interfaceの正しい使い方」で直感的にイメージするものの話をしているmrsekut
「置換可能」って厳密にどういう意味なんだ #??
例えばoverrideはやってもよいのかわるいのか




継承関係のあるものに応用できる
classの継承
Interfaceの利用


ざっくりいうと
①ある箇所で、 を利用している時に、
②その を、 に変えても全く正常に機能する場合にのみ、
は(この順序)で親子関係にできる
に置換可能であるべき」という原則
この図は、最初から と命名しているので、若干語弊があるが、言いたいことはわかるはずmrsekut


classでなくInterfaceでも同じ
Licence というInterfaceと、それを実装している2つの ~~Licence classがある
Billing classはそれらの利用者
Interfaceを用いている場合は、そもそも①のような書き方をしているので
②の置換が可能になる
図の矢印は依存の向きなので、置換の向きではないことに注意mrsekut


この意味で、継承もInterfaceも「リスコフの置換原則を満たしているもの」として同じものと捉えることができる
継承の解説時に「継承はInterfaceだ」のように言われるのは、恐らくこの原則のことを暗に前提している


以下の2つの実装者に対しての注意喚起と言える
継承を作ろうとしている人
今から継承関係のあるclassを作ろうとしている人
今から定義しようとしている、その子classは、親から置換可能ですか?
親のinterfaceのどれを使っても、子は正しく機能しますか?
抽象が存在するものを利用しようとしている人
上の図の 利用者 目線
今から使用しようとしているモノは、具象ではなく抽象に依存していますか?
要はこういうように書け、というもの
ts
const pl: Licence = new PersonalLicence(); // o const pl: PersonalLicence = new PersonalLicence(); // x
PersonalLicence を使う時に、 PersonalLicence の具体的な中身を意識して使うのではなく、 Licence のInterfaceを意識して使えよ、という感じ


継承関係として定義すべきでないものの例

継承を使用できる条件というのが原則だが、
defaultのOOP言語機能として提供される「継承」の作るための制約が弱すぎる
だから何でもかんでも継承にすることができるし、
実際それは原則を守っていないので、ゆくゆく破滅するということが生じる
よってそこに制限を付けるために契約プログラミングの使用があるあるで出てくる
言語機能が貧弱だし、人間も貧弱なので、契約プログラミングしてどうにかしよう、になる



どういう問題が生じるのか #??
リスコフの置換原則を無視して継承を作った時にどういう問題が生じるのか
なぜそもそもそういう原則が存在するのか?






関連