パフォーマンスの変化は、リスコフの代替原則に違反しますか?


14

私が持っていると言う:

interface Thing
{
    GetThing();
}

class FastThing : Thing 
{
    public int GetThing()
    {
        return 1;
    }
}

class SlowThing : Thing
{
    public int GetThing()
    {
        return GetThingFromDatabase();
    }
}

これは、リスコフ代替原則の違反ですか?


GetThingFromDatabase()物議を醸すほど遅くはありません。Factor4096BitPublicKey();return 1;物事をもう少し面白くするでしょう。
パトリック


1
あなたが交換した場合FastThingSlowThing、LSPは適用されません。Thing::GetThing「非常に高速です」というコメントを追加すると、質問を議論できます。
頭足類

回答:


14

それは本当に依存します。一部のインターフェイスには、たとえば、複雑さの制約があります(これらは明らかにプログラムで強制することはできません)。最も基本的なケースは「GetThing()が与えるint-つまり、停止する」です。その場合、答えは「いいえ」となります-GetThing()の両方のバージョンは停止し、intを返します。

しかし、多くのインターフェースは、複雑さまたは平坦な時間のいずれかで、パフォーマンス保証を暗示しているか、明示的に述べています。たとえば、C ++標準では、標準で明示的に許可されている場合を除き、ブロッキング呼び出しでライブラリを実装することは違法です。


3
パフォーマンスは、型チェックによって強制できるものではありません。それは実装者/ライブラリ管理者の約束です。
ダイエット仏

3
私は自分の答えに明示的に述べていますか?
DeadMG

1
私のポイントは、基準にタイプ以外のものを含めるとすぐに、タイプ固有のリスコフについて話さないということでした。異なるパフォーマンスのオブジェクトをサブスクライブしない「練習」は良いかもしれませんが、リスコフ自体はそれについて言うことは何もありません。
-Dietbuddha

7
リスコフは、派生物については、ベースがどこでも使用可能であるべきであると述べています。Baseが特定のパフォーマンスまたは特性を保証している場合、それは正しくない可能性があります。たとえば、Derivedがブロックされると、デッドロックが発生する可能性があります。
-DeadMG

8

TL; DR:いいえ

「不変式と制約を使用した動作サブタイピング」 (原則の形式化)によれば、主にオブジェクトタイプの「安全性」プロパティに関係しています。型情報のコンテキスト内でのみ代替可能性を管理するプロパティ。オブジェクトタイプは、そのパフォーマンスに直交します。したがって、パフォーマンスの違いは、リスコフ代替原則の違反ではありません。


3
私はその論文を少しだけ見てきましたが、タイミング制約を正式に証明できないと確信していますか?そして、たとえリスコフが言葉で、タイミング制約を含むことは、実際のプログラミングに関連するかもしれない古典的なLSPの良い拡張として見ることができることを意味しなかったとしても。
ドックブラウン

@Doc Brown:タ​​イミングがオブジェクトを置換するための考慮事項として役立つかどうかは、リスコフと直交しています。それを別の教訓として追加することができますが、それはリスコフの一部となることはできません。これは、ブール論理式を持ち、!Falseが十分に高速である場合にのみTrueで置換できると言うようなものです。速度は数学や論理とは関係ありません。
dietbuddha

反例:このコードは、JavaのEDTまたはNodeのイベントループで呼び出されます。遅いバージョンの根本的に遅いパフォーマンスは、ソフトウェアを半壊します。この質問に対する適切な答えは「おそらくそうではないが、例外がある」と思う。
user949300

6

インターフェイスは何を保証しますか?GetThing保証がないので、サブタイプはそれを尊重する必要はありません。

インターフェイスが次のようなものであるGetThingInLinearTime場合、または基本タイプが仮想であり、デフォルトの実装が1つの複雑さである場合、そのアルゴリズムの複雑さを悪化させるとLSPに違反します。


4

ソフトウェアのパフォーマンスは、リスコフの代替原理とは関係ありません。

原則は、サブタイプの置換、およびオブジェクトをOOP用語でのみ置換することの動作への影響に関係しています。

の入力と出力はgetThing()両方のケースで同じままであり、低速と高速の両方がオブジェクトを同じ状態にする可能性があります。


1

Liskov Substitution Principle自体が具体的に言っていることは重要ですか?サブタイプがスーパータイプの消費者の期待に違反する場合、LSPがより制限的であるかどうかに関係なく、それは悪いことのように思われます。

したがって、私の見解では、抽象化の消費者に対するすべての合理的な期待がサブタイプによって満たされるかどうかは、LSPの優れた一般化のようです。

ただし、投稿した例と一般的なJavaインターフェースでは、Thingインターフェースのコンシューマーが高速か低速かの合理的な期待を持っているかどうかは明らかではありません。インターフェースのjavadocsに、どの操作が高速であると約束されているかについての言語が含まれている場合、パフォーマンス上の問題の議論があるかもしれません。しかし、Javaの規則は、さまざまな実装が異なるパフォーマンス特性を持つことを確かにしています。


2
私の知る限り、投稿された例はJavaではありません
-gnat

0

ボブおじさんは、LSP違反には3者が必要であると述べている非常に似た質問に答えました。

タイプT、サブタイプS、およびTを使用しているがSのインスタンスが与えられているプログラムP

それは言及していないという点で、私は、この質問は、彼は答えた1と同様の構造を有していることを推測するベンチャー企業ですP使っているTを、どのような行動Pのを期待します。

彼の答えはここにあります。(いくつか下にスクロールして、Robert Martinという名前のユーザーからの回答を探す必要があります)


1
これは質問にどう答えますか?
gnat

@gnat質問は、尋ねたとおり、不完全であるためです。LSP違反を判断するには、3つの当事者が必要です。このうち、彼は2つの当事者のみを提供しました。
TMc
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.