インターフェイスの明示的な実装に基づくトリックを使用して、基本アルゴリズムの実装に必要なメソッドが誤って呼び出されるのを防ぐことができます。ただし、これは安全対策であり、破られる可能性がありますが、開発者が自分が何をしているのかを知っている可能性が高くなります。
必要なメソッドを宣言するインターフェース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 ... }
}
このアプローチの利点は、実装メソッドの偶発的な呼び出しを防ぐことに加えて、実装を子孫にカプセル化するか、別のクラスに分解するかを選択できることです。