2010-01-23 48 views
4

我在什麼情況下你會選擇第一或第二個設計納悶:設計虛擬方法

首先設計:孩子方法必須調用基方法

public abstract class Base 
{ 
    public virtual void Enable() { IsEnable = true; } 
    public virtual void Disable() { IsEnable = false; } 
    public bool IsEnable { get; private set; } 
} 

public class Child : Base 
{ 
    public override void Enable() { /* do stuffs */ base.Enable(); } 
    public override void Disable() { /* do stuffs */ base.Disable(); } 
} 

二設計:一個虛擬的方法用於確保孩子不要忘了基本呼叫

public abstract class Base 
{ 
    public void Enable() 
    { 
     IsEnable = true; 
     OnEnable(); 
    } 

    public void Disable() 
    { 
     IsEnable = false; 
     OnDisable(); 
    } 

    public bool IsEnable { get; private set; } 
    public virtual void OnEnable() {} 
    public virtual void OnDisable() {} 
} 

public class Child : Base 
{ 
    override void OnEnable() { /* do stuffs */ } 
    override void OnDisable() { /* do stuffs */ } 
} 

感謝

+2

我猜你已經自己回答了。當你必須確保基本功能得到執行時使用第二種方法。 –

+0

第二個肯定的是,如果OnEnable/Disable已被beek保護而不是公開的。 –

回答

3

這取決於你是否確實想要確定IsEnable是否被設置。如果您可以想象用戶不想設置它的場景,那麼我想您可以讓他們調用基本方法。否則,爲他們做。

3

第二個,template-based approach在我看來更好。它允許您確保總是調用某些基本功能,併爲您提供空間,以便在沒有任何子類風險的情況下首先添加一些基本功能。

1

在第一個,overring類可以防止設置Enable,我認爲啓用和禁用可能是誤導方法名稱。

類似TryEnable和TryDisable可能會更準確地暗示有些情況下您無法啓用。

第三個可能的情況可以照顧,如果你把例如2,改變它,因此基類設置標誌前調用OnEnable:

public void Enable() 
{ 
    OnEnable(); // Exceptions raised from here prevent the flag being set. 
    IsEnable = true; 
} 

然後重寫類可以防止標誌的設置如果發生錯誤會引發異常。因此錯誤情況會阻止標誌被改變。

只是思考的食物。

2

只要你使一個方法變成虛擬的,你就給派生類有機會打破你的課程。一個負責任的派生者總會問自己:「我應該打電話給基地實施嗎?」對此的指導應始終來自文件。 MSDN使用標準的措辭:

給繼承:

在派生 類中重寫爲Xxxxx,一定要調用基類 的XXXX方法,以便blablah 發生。

C#語言使「base」關鍵字變得簡單。假設本文檔不可用或不清楚,則第二個示例將強烈阻止派生程序調用其他基類方法。畢竟,他/她不會使用標準模式。僅當您想要阻止繼承者調用基類方法時才使用此模式。

+0

我同意添加諸如虛擬方法之類的可擴展性點爲疼痛提供了許多機會,但我不確定我是否將其描述爲脆弱的基類問題。通常情況下,我認爲脆弱的基類問題是*派生類*被基類*改變了。 –

+0

同意後,重新閱讀您的博客文章。編輯。謝謝。 –