2011-10-08 65 views
2

我正在巩固我对Liskov Substitutional校长和开放关闭校长之间关系的理解。如果有人可以证实我的推论,并在下面回答我的问题,那很好。了解Liskov和OCP之间的关系

我有以下类。如您所见,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期待A类型的对象应该很有帮助写出来它是什么类的类型。但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型可以进来,并更改方法的预期功能,它不再对修改关闭(即确保它保持它的预期行为,你将不得不改变它,以便它首先检查以确保我们只处理原始的A对象)?

或者,相反,这只是一个很好的例子,表明ShowClassType已关闭进行修改,并且通过传入派生类型(尽管是违反一个的LSP),我们已经扩展了它的意义所在?

最后,如果基类不是抽象的,在基类上创建虚函数是不好的做法吗?通过这样做,我们不只是邀请派生类来违反Liskov替换原则吗?

干杯

回答

0

我会说这是不是ShowClassType是违反了开/关原则。 只有B级违反了Liskov替代原则。 A是开放的扩展,但关闭修改。 从Wikipedia

实体可允许它的行为,而不改变它的源代码进行修改。

很明显,A的源代码没有被修改。也没有使用A的私人成员(这也违反了我书中的开放/封闭原则)。 B严格使用A的公共接口,所以虽然遵守开放/封闭原则,但是Liskov替换原则被违反。

最后一个问题本身值得讨论。 SO上的相关question就在这里。

0

我认为这不是违反LSP而不是在本使用的上下文中的OCP。

对于我的意见,ShowClassType不违反OCP: 1.功能不能破坏OCP,只有类架构可以做到这一点。 2.您可以将新行为添加到来自A的派生类 - 因此它不会中断OCP

LSP怎么样?你的理由 - 用户不希望得到这个消息?但他得到了一些信息!如果函数覆盖返回一些消息,我认为在你的代码的上下文中是可以的。 如果添加两个数字的函数是覆盖,并且1 + 1返回678,那么对我而言不可预期,并且是不好的。但是,如果对于来自火星行星的物理科学家来说,这可能是一个很好的答案。

不分析问题没有所有的上下文!你必须得到问题的全貌。而且,当然还有