2011-10-08 80 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,那麼對我而言不可預期,並且是不好的。但是,如果對於來自火星行星的物理科學家來說,這可能是一個很好的答案。

不分析問題沒有所有的上下文!你必須得到問題的全貌。而且,當然還有