Leri に基づいて、トラッカーが何をする必要があるかについてもっと考えます。
私はこのようなことをする傾向があります:
public interface ITracker {
void BeginTracking();
void Track(ITrackerEvent trackerEvent);
void EndTracking();
}
そうすれば、すべてのトラッカーはいつ開始し、いつ終了するかを認識できます。トラッカーは、必要以上に長く保持してはならないリソースを保持している可能性があるため、これは重要です。BeginTracking
トラッカーがまたはを使用する必要がない場合EndTracking
、実装は簡単です。些細な実装は、漏れやすい抽象化ではありません。漏れやすい抽象化は、すべての実装で機能しない抽象化です。
ここで、各トラッカーに 2 つのメソッドを追加することに反対しているとします (なぜですか?)。代わりに、帯域外の ITrackerEvents を使用して、Begin と End のセマンティックな意味をカバーすることができます。私はこれが好きではありません。帯域外イベントを処理するには、すべてのトラッカーに特別なコードが必要です。
別のインターフェイスを持つこともできます
public interface IDemarcatedTracker : ITracker {
void BeginTracking();
void EndTracking();
}
ITracker が IDemarcatedTracker であるかどうかを確認するには、呼び出しコードに特殊なコードを含める必要があります。
public void BeginTracking(ITracker tracker)
{
IDemarcatedTracker demarcatedTracker = tracker as IDemarcatedTracker;
if (demarcatedTracker != null)
demarcatedTracker.BeginTracking();
}
あまり大げさなことは言いませんが、トラッカーに障害が発生した場合はどうなるのだろうか? 盲目的に例外をスローするだけですか?そして、ここが抽象化が実際に漏れやすいところです。トラッカーが追跡できないことを知らせるプロセスはありません。
あなたのケースでは、ブール値 (限られた情報)、エラー コード (やや詳細な情報)、またはエラー クラス/構造体を返したい場合があります。または、スローされる標準例外が必要な場合もあります。または、トラッキングでエラーが発生したときに呼び出すデリゲートを Begin() メソッドに含めることができます。