3

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

这是我简化的基类实现:

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

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

4

1 回答 1

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

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

于 2012-09-30T16:39:12.917 回答