5

ITracker次のようなインターフェイスを実装しています。

public interface ITracker
{
    void Track(ITrackerEvent trackerEvent);
}

最初に、Mixpanel.NET をラップするこのインターフェイスの実装を作成しました。次に、Application Insights をラップする別のものを作成しました。ただし、Application Insights ではFlush()、データをサーバーに送信する必要があります。

実装の1つがメソッドを必要とするという理由だけITrackerで、メソッドでインターフェイスを汚染したくありません。Flush()漏れやすい抽象化のように感じるでしょう。

ただし、ある時点 (おそらくアプリケーションのシャットダウン時) でこのメソッドを呼び出す必要があり、呼び出されるたびに呼び出したくありませんTrack

セッションの最後にトラッカーがガベージ コレクションされるときにメソッドを呼び出すことは可能ですか? これも良いアプローチですか?

ここでトリックを逃したような気がします!

4

4 に答える 4

5

ITrackerトラッカーイベントを破棄したり、ロールバックしたり、変更したりする場合があるため、トランザクションに似たパターンを使用するようにします。

public interface ITracker
{
    void Track(ITrackerEvent trackerEvent);

    void Commit();
}

そして、実装ごとに:

  • アプリケーションの洞察を得るためにFlush内部に電話します。Commit
  • メソッド内のインメモリ コレクション (List<ITrackerEvent>またはBlockingCollection<ITrackerEvent>同時実行が関係する場合) にトラッカー イベントを記述し、現在のロジックを使用して、メソッドの実装内で APITrackを呼び出します。Mixpanel.NETCommitMixpanel.NET

推奨事項: トラッカーは通常、破棄する必要があるリソースを使用するため、ITracker実装する必要があります。IDisposable

于 2016-03-09T13:32:04.750 に答える
5

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() メソッドに含めることができます。

于 2016-03-09T13:59:21.290 に答える
1

何かをバッファリングしているように聞こえます-追跡されるものは時々フラッシュされる必要があります。あなたのインターフェイスはその動作を隠します。これは良いことです.フラッシュされているとき、またはバッファリングされているときでさえ、そのインターフェイスからはわからないはずです。

ボリュームが大きい場合は、最大フラッシュ間隔と最大バッファ サイズの 2 つのパラメータを設定します。1 つ目は、タイマーを使用して定期的にフラッシュします。2 つ目は、容量に達したときにフラッシュをトリガーします。そして、オブジェクトが破棄または収集されるときに再度フラッシュします。

バッファを独自のクラスに分離して、再利用して個別に単体テストできるようにしました。見つけられるかどうかはわかりますが、書くコードはそれほど多くありません。

于 2016-03-10T02:41:19.817 に答える