模板方法模式 - 阻止派生类中的直接方法调用

时间:2012-09-30 16:12:46

标签: c# algorithm design-patterns abstract-class template-method-pattern

我不确定我是否正确理解模板方法模式。

这是我简化的基类实现:

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

据我所知,基类知道算法流程并对其进行管理。 问题是在实际项目中我有很多抽象方法,如果我能以某种方式阻止在派生类中直接调用它们会很好。当多个类管理算法流程时,它是不可读的。

1 个答案:

答案 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的特定算法类使用显式接口实现来封装必要方法的实现(比如在基类中声明的抽象方法),同时防止它们被意外调用:

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 ... }
}

这个approch的优点 - 除了防止意外调用实现方法之外 - 还可以选择是将实现封装在后代中,还是将其分解为单独的类。

相关问题