2

Liskov Substitutional Principal と Open Close Principal の関係についての理解を深めています。誰かが私の推論を確認し、以下の私の質問に答えてくれれば、それは素晴らしいことです.

私は次のクラスを持っています。ご覧のとおり、Bから派生し、動作を変更するために関数をAオーバーライドしています。DisplayMessage

public class A
{
    private readonly string _message;

    public A(string message)
    {
        _message = message;
    }

    public virtual void DisplayMessage()
    {
        Console.WriteLine(_message);
    }
}

public class B : A
{
    public B(string message) : base(message){}

    public override void DisplayMessage()
    {
        Console.WriteLine("I'm overwriting the expected behavior of A::DisplayMessage() and violating LSP >:-D");
    }
}

今、私のブートストラップ プログラムではShowClassTypeis、Type のオブジェクトを期待しています。これは、TypeAがどのクラスであるかを書き出すのに役立ちます。ただしB、LSP に違反しているため、そのDisplayMessage関数が呼び出されると、完全に予期しないメッセージが出力され、本質的に の意図された目的が妨げられShowClassTypeます。

class Program
{
    static void Main(string[] args)
    {
        A a = new A("I am A");
        B b = new B("I am B");

        DoStuff(b);

        Console.ReadLine();
    }

    private static void ShowClassType(A model)
    {
        Console.WriteLine("What Class are you??");
        model.DisplayMessage();
    }
}

だから私の質問は、ShowClassTypeタイプ B が入ってきてそのメソッドの期待される機能を変更できるようになったので、それはもはや変更のために閉じられていないため、Open Close Principal に違反していると結論付けるのは正しいですか?元の A オブジェクトのみを操作していることを最初に確認するように変更する必要があると予想される動作)?

ShowClassTypeまたは、逆に、これは変更に対して閉じられていること、および派生型を渡すことによって (LSP に違反しているものの) 意図されていることを拡張したことを示す単なる良い例ですか?

最後に、基本クラスが抽象クラスでない場合、基本クラスに仮想関数を作成するのは悪い習慣ですか? そうすることで、派生クラスをリスコフ置換の原則に違反するように誘っているだけではありませんか?

乾杯

4

2 に答える 2

0

ShowClassTypeオープン/クローズの原則に違反しているとは言えません。Liskov Substitution Principleに違反しているのはクラスBだけです。A は拡張用に開いていますが、変更用に閉じています。ウィキペディアから、

エンティティは、ソース コードを変更せずに動作を変更できます。

A のソース コードが変更されていないことは明らかです。また、A のプライベート メンバーも使用されていません (これは、私の本のオープン/クローズの原則に違反することにもなります)。B は A のパブリック インターフェイスを厳密に使用するため、Open/Closed 原則には従いますが、Liskov Substitution Principle には違反しています。

最後の質問は、それ自体で議論する価値があります。SOに関する関連する質問はこちらです。

于 2011-10-08T06:59:46.640 に答える
0

この使用のコンテキストでは、LSPでもOCPでも違反ではないと思います。

私の意見では、ShowClassType は OCP に違反していません: 1. 関数は OCP を破ることはできません。2. A から派生したクラスに新しい動作を追加できるため、OCP が壊れることはありません

LSPはどうですか?あなたの理由 - ユーザーがこのメッセージを受け取ることは想定されていませんか? しかし、彼はいくつかのメッセージを受け取りました!関数のオーバーライドが何らかのメッセージを返す場合、コードのこのコンテキストでは問題ないと思います。関数の場合、2 つの数値を追加するのはオーバーライドであり、1+1 は 678 を返します。これは私には期待できず、悪いことです。しかし、火星の物理学の科学者にとって、それは良い答えになる可能性があります.

すべてのコンテキストなしで問題を分析しないでください!!! 問題の全体像を把握する必要があります。そしてもちろん

于 2012-05-10T08:02:19.660 に答える