問題タブ [liskov-substitution-principle]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - 階層はリスコフに違反します-それで何ですか?
Liskov置換原則に違反するAPIを使用しています。これは、Exceptionを拡張する独自のExceptionタイプをスローしますが、基本クラスからの例外メッセージを新しいErrorCodeフィールドに入れ、独自の(役に立たない)メッセージをMessageフィールドに入れます。したがって、正しいメッセージを表示するには、例外をDerivedExceptionタイプにキャストし、ErrorCodeフィールドを使用する必要があります。例外オブジェクトとして扱うと、間違ったメッセージが表示されます。
これは文体レベルで私を苛立たせますが、回避するのは簡単です。DerivedExceptionをキャッチして、プログラマーが意図したとおりに使用できます。だから私の質問はこれです:リスコフの原則についての大したことは何ですか?原則に違反する階層を使用して人々が遭遇する可能性のある実際的な問題は何ですか?
design-patterns - バインドのためにLSPを壊しても大丈夫ですか?
何かが私にこれを尋ねるためにリンチされるかもしれないと私に言います。そして、事前に長い説明をしてすみません。
私はSilverlight4プロジェクトのコーナーケースのようなものに取り組んでいます。基本的に、私が構築しているのはカスタムフォームビルダーです。
フォームには、さまざまなタイプ(テキスト、整数、電子メールなど)のフィールドがいくつかある場合があります。現在、これらのタイプはすべてField
クラスを拡張していますが、テキストフィールドの場合は長さなどの追加のプロパティがある場合があります。
のコレクションからフィールドを追加および削除することができFieldViewModels
ますFormFieldsManagementViewModel
。つまり、これまでのところ、すべてかなり標準的なものです。
さて、...ユーザーがFieldオブジェクトに対してプロパティを設定するために、UserControl
タイプの依存関係プロパティを持ちDataTemplate
、特定のタイプのフィールドが選択されたときにディッププレイしたいUIを表すがあります。したがって、明確にするために、は、aが選択されたときに表示されるプロパティをUserControl
持っていますが、aが選択されたときに表示されます。と継承元の両方。SingleLineTextTemplate
SingleLineTextFieldViewModel
EmailFieldViewModel
EmailFieldTemplate
SingleLineTextFieldViewModel
EmailFieldViewModel
FieldViewModel
これらの各テンプレートでバインディングを宣言すると、問題が発生します。FieldViewModel
のような基本クラスのプロパティIsRequired
を設定することは非常に有効です(IMHO)が、の長さプロパティに一致するのPosition
バインディングもあります。したがって、私はクラスだけでなく、具象クラスの拡張インターフェースに依存しています。Length
SingleLineTextTemplate
SingleLineTextFieldViewModel
FieldViewModel
先に進む前に、これが機能することを指摘する必要があります。私はそれがそうなるかどうか確信がありませんでした、そして今それはそうするべきであるかどうか、または私がこれをするべきであるかどうかさえわかりません。
これは、バインドのために、動的オブジェクトへのバインドがない場合、および/またはDataTemplateSelector
Silverlightがない場合にのみ実行しています。
明らかに、バインディングシナリオでは基本クラスの代わりにSingleLineTextFieldViewModel
はなりません。私の質問は、これらのオブジェクトをコードではなくマークアップで実際に消費しているので、..これはまだ悪い習慣と見なされていますか?
よろしくお願いします。
liskov-substitution-principle - Liskov と OCP の関係を理解する
Liskov Substitutional Principal と Open Close Principal の関係についての理解を深めています。誰かが私の推論を確認し、以下の私の質問に答えてくれれば、それは素晴らしいことです.
私は次のクラスを持っています。ご覧のとおり、B
から派生し、動作を変更するために関数をA
オーバーライドしています。DisplayMessage
今、私のブートストラップ プログラムではShowClassTypeis
、Type のオブジェクトを期待しています。これは、TypeA
がどのクラスであるかを書き出すのに役立ちます。ただしB
、LSP に違反しているため、そのDisplayMessage
関数が呼び出されると、完全に予期しないメッセージが出力され、本質的に の意図された目的が妨げられShowClassType
ます。
だから私の質問は、ShowClassType
タイプ B が入ってきてそのメソッドの期待される機能を変更できるようになったので、それはもはや変更のために閉じられていないため、Open Close Principal に違反していると結論付けるのは正しいですか?元の A オブジェクトのみを操作していることを最初に確認するように変更する必要があると予想される動作)?
ShowClassType
または、逆に、これは変更に対して閉じられていること、および派生型を渡すことによって (LSP に違反しているものの) 意図されていることを拡張したことを示す単なる良い例ですか?
最後に、基本クラスが抽象クラスでない場合、基本クラスに仮想関数を作成するのは悪い習慣ですか? そうすることで、派生クラスをリスコフ置換の原則に違反するように誘っているだけではありませんか?
乾杯
gwt - GWT の ActivityMapper は Liskov Substitution Principle に違反していますか?
私の GWT アプリケーションには、次のようなクラスがあります。
ActivityMapper、Activity、および Place オブジェクトはフレームワークの一部であり、インターフェイスは、これが意図された使用方法であることを暗示しています。
ただし、Liskov Substitution Principleによると、型を受け入れるが、サブクラスの型チェックを行って、実行するアクションを推測するメソッドは、原則に違反しています。
GWT の ActivityMapper インターフェースは、本質的に LSP の違反を助長していますか? または、私が考えもしなかった方法をコーディングする別の LSP 準拠の方法はありますか?
liskov-substitution-principle - Liskov 置換原理 - オーバーライド メソッドの例
この本当に些細なクラスがあるとしましょう:
この例は LSP に違反しますか? もしそうなら、原則を破らず、別の実装を使用する例を教えてください。
これはどうですか:
私が理解している限り、変数「変数」を使用すると、より強力な前提条件が発生するため、LSP に違反します。しかし、ポリモーフィズムを使用するときに LSP に従う方法が完全にはわかりません。
java - この場合、LSP(リスコフの置換)に違反することはできますか?
アイテムのリストを宣言するモデル抽象クラスがあります。抽象には2つの抽象クラスがあります。リストに新しいアイテムを追加できるものと、リストをまったく使用しないが、それ以外の場合はモデル抽象クラスの他の動作に準拠するもの。
リストからアイテムを追加および削除する2つのメソッドを宣言しました。明らかに、これらのメソッドを使用するときはいつでも、モデル抽象をそのサブクラスでキャストする必要があります。
この場合、 LSP(リスコフの置換原則)に違反することはできますか?または、この問題を回避する方法はありますか?
python - クラスの継承: コンストラクターは互換性があるべきですか? 多重継承の場合?
オブジェクト指向プログラミングの推奨原則の 1 つは、リスコフ置換原則です。サブクラスは、その基本クラスと同じように動作する必要があります (警告: これは、実際にはリスコフ原則の正しい説明ではありません: PS を参照してください)。 .
コンストラクターにも適用することをお勧めしますか? 私は主に Python とその__init__()
メソッドを念頭に置いていますが、この質問は継承を使用するすべてのオブジェクト指向言語に当てはまります。
私がこの質問をしている理由は、サブクラスが 1 つまたは複数のクラスから継承して、いくつかの優れたデフォルトの動作を提供することが役立つ場合があるためです (Python での辞書からの継承のようobj['key']
に、新しいクラスのオブジェクトに対して機能します)。ただし、サブクラスを辞書とまったく同じように使用できるようにすることは、常に自然または単純であるとは限りません。コンストラクターのパラメーターを特定のユーザー サブクラス (たとえば、一連のシリアル ポートを表すクラス) のみに関連付ける方がよい場合があります。辞書のように振る舞いたいかもしれませんports['usb1']
USB ポート #1 など)。そのような状況への推奨されるアプローチは何ですか? 基本クラスのコンストラクターと完全に互換性のあるサブクラス コンストラクターを持ち、シンプルで使いやすいパラメーターを取るオブジェクト ファクトリ関数を介してインスタンスを生成しますか? または、基本クラスのコンストラクターにパラメーターのセットを直接渡すことができないクラス コンストラクターを単に作成しますが、ユーザーの観点からはどちらがより論理的でしょうか?
PS : 上記の Liskov の原則を誤解しました: 以下の Sven のコメントは、サブクラスのオブジェクトはスーパークラスのオブジェクトのように振る舞うべきであるという事実を指摘しています (サブクラス自体はスーパークラスのように振る舞う必要はありません; 特に、それらのコンストラクターには同じパラメーター [署名] を持つ)。
oop - 独占ゲーム - LSP OO の原理
モノポリー ゲームを設計しながら、OO の原則についても詳しく調べています。LSP (Liskov Substitution Principle) について読んでいて、それを完全に理解していないか、違反しているため、設計を変更する必要があることがわかりました。
(注記: このプロジェクトは個人的な楽しみのためのものなので、実際にはコードの保守性は気にしませんが、個人的な教育と LSP の理解を求めているだけです)
これまでに設計したものから始めましょう。
クラスBoardSpace
は抽象基本クラスであり、ボード上の「種類」のスペースごとに 1 つのサブクラスがあります。だから私は、、、PropertySpace
などTaxSpace
を持っていますGoSpace
。
BoardSpace
スペースがボード上のどこにあるかに関する情報と抽象void Land()
メソッドを持っているため、それぞれの異なるスペースに着陸したときに異なることを行うことができます。Land()
そうすれば、現在のオブジェクトを呼び出しているときにBoardSpace
、他のことを気にしたり考えたりする必要がなく、スペースがすべきことを行うだけです。私にとって、これは理にかなっており、実行可能なソリューションのように思えます。
Land()
しかし、私が設計したように、これらの異なるオーバーライドされたメソッドはすべてまったく異なることを行うという点で、LSP に反しているようです。
または、LSP を誤解していますか? Land()
「期待される」または「説明される」方法と関係がありますか?この場合、どれがスペースごとに完全に異なるので大丈夫ですか? それとも、それは確かに違反であり、再設計する必要がありますか?
副次的な質問: これは継承の「乱用」と見なされますか、それとも有効な使用と見なされますか?