2

我不確定是否正確理解模板方法模式。模板方法模式 - 防止派生類中的直接方法調用

這裏是我的簡單基類實現:

public abstract class AlgorithmBase 
{ 
    protected void AlgorithmMethod() 
    { 
     if(!OnSimulationStart()) 
     { 
      OnSimulationEnd(false); 
      return; 
     } 

     if(!DoSomeStep()) 
     { 
      OnSimulationEnd(false); 
      return; 
     } 

     OnSimulationEnd(true); 
    } 

    protected abstract bool OnSimulationStart(); 
    protected abstract bool DoSomeStep(); 
    protected abstract void OnSimulationEnd(bool result); 
} 

據我瞭解,基類知道算法流程,並對其進行管理。 問題是,在真實的項目中,我有很多抽象方法,如果我能以某種方式阻止在派生類中直接調用它們,那將會很好。當多個班級管理算法流程時,這是不可讀的。

+0

你會問這種模式? –

+0

你的意思是,我的具體情況是什麼? – Kuba

+0

你能發佈一個你試圖防止的情況的非平凡的例子嗎?當你不得不擔心不恰當地使用這些抽象方法時,很可能你沒有適當地分解你的問題。 –

回答

1

基於顯式實現接口的技巧可用於防止基礎算法實現所需的方法的意外調用。然而,這是一個可以被破壞的安全措施,但是開發人員知道他會做什麼的可能性很高。

的接口聲明由AlgorithmMethod所需的方法:

使用此接口,傳遞到它的構造函數,調用所需的方法
public interface IAlgorithmMethodImpl 
{ 
    bool OnSimulationStart(); 
    bool DoSomeStep(); 
    void OnSimulationEnd(bool result); 
} 

抽象基類:

public abstract class AlgorithmBase 
{ 
    protected AlgorithmBase(IAlgorithmMethodImpl impl) 
    { 
     Impl = impl; 
    } 

    // can be a property reasonable cases; however, a field 
    // fits well into our scenario 
    private IAlgorithmMethodImpl Impl; 

    protected void AlgorithmMethod() 
    { 
     if(!Impl.OnSimulationStart()) 
     { 
      Impl.OnSimulationEnd(false); 
      return; 
     } 

     if(!DoSomeStep()) 
     { 
      Impl.OnSimulationEnd(false); 
      return; 
     } 

     Impl.OnSimulationEnd(true); 
    } 

    // no abstract method declarations here — they are provided by 'Impl' 
} 

那麼具體的算法類從AlgorithmBase繼承使用顯式接口實現來封裝必要方法的實現(如使用基類中聲明的抽象方法),同時阻止它們被調用acci牙齒:

public class MySuperAlgorithm : AlgorithmBase, IAlgorithmMethodImpl 
{ 
    public MySuperAlgorithm() 
     // pass a reference to this instance as the class 
     // that implements the required methods 
     : base(this) 
    { 
    } 

    // explicit implementation of IAlgorithmMethodImpl 
    bool IAlgorithmMethodImpl.OnSimulationStart() { ... implementation ... } 
    bool IAlgorithmMethodImpl.DoSomeStep() { ... implementation ... } 
    void IAlgorithmMethodImpl.OnSimulationEnd(bool result) { ... implementation ... } 
} 

這個計算策略的優勢 - 除了防止的實現方法調用意外 - 是,你可以選擇是否封裝實施後代,或將其分解成一個單獨的類。

+0

不錯的訣竅:) 我在你的例子中喜歡的另一件事是,我們甚至可以進一步去除算法實現中AlgorithmBase派生類的實現。 – Kuba

+0

是的,解耦是您在實施中應該尋求的質量。如果將來驗證您的代碼。 –