リスコフ置換原則への取り組み(続々、Birthday改めBirthdate問題、もしくは、僕たちはフインキで型安全している)
- Tanaka9230
- 7195
- 16
- 0
- 0
@tenjuu99 LSPが言ってるのは、派生クラスはシグネチャや構造が合ってさえいれば良いわけではなく、振る舞い仕様も継承しなさい、という話で、元々プログラマーが気を付けるべきガイドラインだと理解してます。(続
2019-09-12 22:46:08@tenjuu99 この理解を前提に、 自分がいいたいことは、、継承ツリー全てimmutableオブジェクトとして仕立てよというルールの元だったら、LSP違反な、つまり振る舞い仕様を継承してないような派生クラスというのは、(良心的に開発している限り)誤って作り出すことが無いのではないか、、ということとなります。
2019-09-12 22:49:57@Tanaka9230 うーん、僕の手に余る問題なのですが、リスコフ置換原則はプログラマーが守るべき原則というより「subtypeとは何か」という定義そのもののように見えます。円-楕円問題などは背理法的に型はクラスでないという証明をしているように見えます。
2019-09-13 11:47:59@Tanaka9230 この理解が正しいとしてですが、田中さんがリスコフがsubtypeに課した条件に対してもう一つimmutableという条件を付け加えるのはよくわかりませんでした。現場レベルではそれで困らないとも思うのですが、条件を増やすより「トレードオフで型安全ではないよ」と明言したほうが早いと思いました。
2019-09-13 11:49:21@Tanaka9230 あと、immutableであればLSP違反にならないということに対しては以下の記事がありました。 okmij.org/ftp/Computatio…
2019-09-13 12:10:37@polidog 「派生型は派生元と完全な互換性を維持しなければならない」という言明は派生型の定義だと思うのですが、nominal subtypingの場合、円-楕円のように派生型の定義を守れないことがあり、要求を満たすことができない、つまりnominalなsubtypeはsubtypeとは呼べないという論理に見えました
2019-09-13 14:53:22LSPが破られるとき、それって派生型の問題というよりは基底型が振る舞いを持ちすぎって話になりませんかね。まあどっちも問題というか、継承の問題なんですけど。
2019-09-13 18:50:20@magnolia_k_ @tenjuu99 派生型の定義を守れるかによって継承すべきかは変わってくるんですかね。 ただ守れるかどうかの判断ってすごく難しいですよね...
2019-09-13 19:16:04@polidog @magnolia_k_ @tenjuu99 議論の流れがよくわかっていないのですけど、楕円から派生させて円を作るとLSPに違反するんでしょうか? 円とは2つの焦点が同一である楕円に過ぎないような感じがするのですが。
2019-09-13 19:29:37@sugimoto_kei @polidog @tenjuu99 二つの話を混ぜちゃったのがアレですけど、一つの疑問は、継承の方向を楕円の特殊なパターンが円って解釈だとスッキリしました
2019-09-13 20:36:04@magnolia_k_ @polidog @tenjuu99 あ、なるほど。そういうことですか。円が親だとLSP違反になりますね。
2019-09-13 20:39:48@sugimoto_kei @polidog @tenjuu99 そうです、そうゆう間違った方向の継承にしてしまってLSP満たさない設計にならないように設計するべきなんだけど、それは難しいですねーって話でした
2019-09-13 20:57:54@magnolia_k_ @sugimoto_kei @polidog @tenjuu99 横からですが、円・楕円問題で例として挙げられてるのは(あくまで楕円が親で)「引き伸ばす」という内部状態を変える振る舞いがあったとして、派生型である円が「2つの焦点は同一である」という不変条件を満たさなければならない場合、それは実装不可能ですねっていう話です。
2019-09-13 21:35:41@magnolia_k_ @sugimoto_kei @polidog @tenjuu99 たとえば昨今の流行り(?)っぽく、内部状態を変えるのではなく変更された結果のインスタンスを返すという振る舞いであればレシーバーが楕円でも円でも戻り値として楕円を返せばいいのでLSPには違反しないと思いますね。
2019-09-13 21:38:03@tenjuu99 記事紹介ありがとうございます。 まず、僕はsubtypingとsubclassingを区別できていない。 記事でも「オブジェクト派生がsubtypingになるケースとならないケースがある」ように書いてある。つまり「円は楕円のサブクラスだが、サブタイプではない」と。でLSPはサブタイプ条件を言っている。
2019-09-13 22:01:12@a_suenami @magnolia_k_ @polidog @tenjuu99 なるほど。だけど、「引き延ばせる楕円」の派生型としての「引き延ばせる円」が存在しないのは、当たり前のような気もします。円は引き延ばせないですから。
2019-09-13 22:01:38