Hatena::ブログ(Diary)

西尾泰和のはてなダイアリー

2013-08-24

リスコフの置換原則

拙著「コーディングを支える技術」のp.216では、リスコフの置換原則について説明しています。しかし、p.217の「条件qを満たさないTが発生する」という表現はわかりにくいようですので、ここでストーリー仕立てにして補足説明をします

今日

まず、現時点でT型の値はすべて条件qを満たしているとします。

あなたはT型の引数をとる関数fを実装したいとします。あなたはきっと「T型の値はすべて条件qを満たしている」ということを前提としてコードを書くことでしょう。

1ヶ月後

あなたはSを作ろうと考えます。S型の値の中には条件qを満たさないものもありますが、あなたはあまり意識していません。

あなたは「SはTを継承して作ると楽だな」と思ったので、そうしました。

Javaなどの言語処理系では、SがTを継承すると、T型の変数にS型の値を入れることができるようになります。つまりこの時点でT型の引数を取る関数fにS型の値を渡すことも可能になっています。

さらに1ヶ月後

あなたが2ヶ月前に実装した「T型の値を引数にとる関数f」の中で問題が起きます。

T型の値はすべて条件qを満たすはずなのに、条件qが満たされているなら起こりえないようなことが起こっています。あなたは悩みます。

あなたは原因が条件qを満たさないS型の値が引数に渡されていることだと気づきました。そこでif文で分岐して2通りの処理を書くことにしました。

これでよいのでしょうか?いや、違いますね。この2ヶ月の間に書かれた他のT型の値を扱うコードも、条件qを満たさない値だと問題が起きるかもしれません。この種のバグは、1匹目を見つけた頃には既に何十匹も物陰に潜んでいるのです。

あなたが次々出てくるバグに悩まされて、別の人に相談します。そして「なんでSはTを継承したんだ」と指摘されたとしましょう。でも、こういう状況って既にSを書きなおすことができない状況になっていたりするわけです。

さいごに

このエントリーではリスコフの指摘した「置換原則を満たしていない場合に起こる問題」を、時系列に並べて解説してみました。書籍の方は紙面の制約がありますが、なんとかわかりやすくなるように修正したいと思います。

拙著「コーディングを支える技術」の読者のみなさんから頂いたご質問・ご感想には、このような感じで補足記事を書いて行きたいと思っています。おきがねなくご質問・ご感想をお寄せ下さい。

拙著に関する他のエントリーは「「コーディングを支える技術」著者公式ページ」からたどれるようにします。

問い合わせした者問い合わせした者 2013/08/24 20:57 先日、この件について問い合わせした者です。

p.217の図12.5 右側の図にて、S型の値が条件qからはみ出していて、T型の値は条件qからはみ出していなかったので、p.217の6〜7行目の「条件qを満たさないT」は、「条件qを満たさないS」ではないか?と早とちりしてしまいました!

整理するつもりで自分の言葉で表してみます。
条件qを満たさないS型のオブジェクトを、T型のクラスに代入したことにより「条件qを満たさないT」が生まれてしまった、ということですよね?

間違いではなかったのですね・・自分の勘違いしていた所に気づけました!
お騒がせしてすみません><
ありがとうございました!

nishiohirokazunishiohirokazu 2013/08/29 23:20 お役に立てたようで幸いです!
こういう質問をいただけると、説明のわかりにくい場所がどこか明確になるので助かります。
今後ともぜひよろしくお願いします!

投稿したコメントは管理者が承認するまで公開されません。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/nishiohirokazu/20130824/1377333960