テンプレートメソッドパターン - 派生クラスでの直接メソッド呼び出しを防ぐ
-
11-12-2019 - |
質問
テンプレートメソッドパターンを正しく理解しているかどうかわからない。
これは私の単純化された基本クラスの実装です:
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);
}
.
私が理解している限り、基本クラスはアルゴリズムの流れを知って管理します。 問題は、実際のプロジェクトでは多くの抽象的な方法があることです。私がどういうわけか派生クラスで直接呼び出すことを防ぐことができればいいでしょう。複数のクラスがアルゴリズムの流れを管理するときは、読めません。
解決
インタフェースの明示的な実装に基づくトリックを使用して、基本アルゴリスの実装によって必要とされる方法の偶発的な呼び出しを防ぐことができます。しかし、それは壊れている可能性がある安全措置ですが、開発者が彼が何をしているのか知っている可能性が高いという性が高いです。
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 ... }
}
.
実装方法の偶発的な呼び出しを防ぐために、この承認方法の利点 - 子孫の実装をカプセル化するか、別のクラスに分解するかを選択できることです。
所属していません StackOverflow