ほとんどすべてのプログラマーは、自分の人生の中で一度、変数の値が変更された場合にフラグを設定しました。常に多くのプロパティがあり、何かが変更された場合に追跡したい
上記の状況で「ダーティフラグ」機能を実装するさまざまな方法に興味があります、プロパティの変更ごとに更新される標準のオブジェクト全体のダーティフラグ。各セッターに "dirty = true"を置くよりも良いものがあるはずです:見た目が悪く、退屈な作業です。
DAOの場合、データベースから取得した元の値のコピーを保持します。更新するために送信するときは、元の値と現在の値を比較するだけです。処理には少しコストがかかりますが、プロパティごとにダーティフラグを設定するよりもはるかに優れています。
ダーティフラグがないことをさらに正当化するための編集:プロパティが元の値に戻った場合、それを反映する方法はありません。元の値が失われたため、ダーティフラグはダーティのままです。
かつては、基本エンティティクラスがあり、ダーティ/削除されたロジックを提供していました。
エンティティサブクラスを書くとき、あなたは次のようなことをすることができます:
public string Name
{
get { return name; }
set { setValue("Name", value); }
}
これは正常に機能しますが、「醜いひも」疾患を持っています...
今日、ラムダ式を使用して文字列を除外できます。
set {setValue(x => x.Name, value);}
または、これが最良の解決策だと思います [〜#〜] aop [〜#〜] を使用できます:
このように、属性によってアクションを定義できます。属性を作成し、ユーザーが関連するプロパティを変更するとエンティティがダーティになるように指定します。
さらに、変更されたプロパティを記憶するクラス(ベースエンティティ)にプロパティのリストを保持し、AOPコードからそのリストにアクセスできます。
元の値と現在の値を持つDirtyValue<T>
というクラスを作成しました。最初の使用時に、元の値と現在の値の両方を設定します。連続して呼び出すと、現在の値のみが設定されます。
IsDirty()と呼ばれる読み取り専用のboolプロパティを使用して、2つを比較することにより、変更されたかどうかを確認できます。この手法を使用すると、元の値にもアクセスできます。
「ダーティ」フラグを設定する場合は、状態を保持していることを認識してください。ある時点で、その状態に基づいてアクションを実行する必要があります。それ以外の場合は、フラグを保持する必要はありません。したがって、問題は次のようになります。必要なアクションをトリガーする別の方法はありますか?何らかのメッセージを送信しますか? 「ダーティ」状態を使用してアクションを実行するのは誰ですか。その通知のためのより明確なインターフェイスはありますか?
データライタータスクと独立したリーダータスクがある状況では、各タスクにupdateCount
変数を指定しました。プロデューサーは、書き込むたびにカウントを増やします。リーダーがウェイクアップし、その数がプロデューサーの数よりも少ないことを検出するたびに、リーダーは現在の値で更新を行います。カウンターオーバーフローには少し特別な処理が必要ですが、これは簡単に実装できます。
私はこのテクニックをシミュレーションで首尾よく使用しました-プロデューサーは物理ループであり、リーダーは3Dディスプレイです。
各セッターにchanged()を入れます。つまり、フラグを変更するだけでなく、プライベートメソッドを呼び出します。次に、メソッドはフラグを設定するか、必要な処理を実行します。オブザーバーに通知することもできます。
明示的なdirty=true
アプローチの興味深い代替手段は、ほとんどの状況ではおそらくやり過ぎであり、多くの場合適用されませんが、ガードページを使用することです。メモリページを読み取り専用に設定し(たとえば、Windowsで VirtualProtect() を使用)、プログラムがページに書き込もうとしたときに信号/例外をキャッチします。ページが変更されたことを記録し、ページの保護フラグを書き込み可能に変更して、実行を再開します。
これは、ページがRAMから削除される前にページをスワップファイルに書き込む必要があるかどうかを判断するためにオペレーティングシステムで通常使用される手法です。