質問

I am solidifying my understanding of the relationship between Liskov Substitutional Principal and Open Close Principal. If anybody could confirm my deductions and answer my questions below that would be great.

I have the following classes. As you can see, B is derived from A and it is overriding the DisplayMessage function in order to alter the behavior.

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");
    }
}

Now in my bootstrap program, ShowClassTypeis expecting an object of Type A which should helpfully write out what class Type it is. However B is violating LSP so when it's DisplayMessage function is called it prints a completely unexpected message and essentially interferes with the intended purpose of 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();
    }
}

So my question is, am I right to conclude that ShowClassType is now violating the Open Close Principal because now that Type B can come in and change the expected function of that method, it is no longer closed for modification (ie. to ensure it maintains it's expected behaviour you would have to alter it so that it first checks to make sure we are only working with an original A object)?

Or, inversely is this just a good example to show that ShowClassType is closed for modification and that by passing in a derived type (albeit a LSP violating one) we have extended what it is meant to do?

Lastly, is it bad practice to create virtual functions on Base classes if the base class is not abstract? By doing so, are we not just inviting derived classes to violate the Liskov Substitution principal?

Cheers

役に立ちましたか?

解決

I'd say it's not ShowClassType that is violating the Open/Closed Principle. It's only class B that is violating the Liskov Substitution Principle. A is Open for extension, but closed for modification. From Wikipedia,

an entity can allow its behaviour to be modified without altering its source code.

It's obvious that the source code of A is not modified. Nor are private members of A being used (which would also be a violation of the Open/Closed principle in my book). B strictly uses the public interface of A, so although the Open/Closed principle is obeyed the Liskov Substitution Principle is violated.

The last question is worth a discussion in and of itself. A related question on SO is here.

他のヒント

I think it is not violate not LSP and not OCP in THIS context of using.

For my opinion, ShowClassType not violation OCP: 1. Function can not break OCP, only class architecture can do this. 2. You can add new behaviours to derived classes from A - so it do not break OCP

What about LSP? Your reason - user not expected get this message? But he got some message! If function overriding returns some message i think is ok in THIS context of your code. If function, that add two numbers is overrides, and 1+1 returns 678 it not expectable for me and is bad. BUT, if for scientist of Physics from Mars planet it can be good answer.

DO NOT ANALYSE PROBLEM WITHOUT ALL CONTEXT!!! You must get whole picture of problem. And, of course

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top