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 に答える