3

この質問は、私の質問Different ways ofobserver data changes を改良したものです。

私の C++ アプリケーションにはまだ多くのクラスがあり、それらは複雑な数学ルーチンやビジネス ロジックの複雑な部分で頻繁に更新されます (または更新される可能性があります)。

「オブザーバー」アプローチを採用し、インスタンスの値が変更されるたびに通知を送信すると、2 つの大きなリスクがあります。

  • 通知自体を送信すると、アプリケーションの速度が大幅に低下する可能性があります
  • 変更によってユーザー インターフェイス要素を更新する必要がある場合、それらは変更のたびに更新されます。その結果、たとえば、ビジネス ロジックの一部が実行されている間に画面が何千回も更新されます。

いくつかの問題は、バッファリング メカニズム (アルゴリズムの開始時とアルゴリズムの終了時に通知を送信するメカニズム) を追加することで解決される可能性がありますが、ビジネス ロジックはソフトウェアの多くの場所で実行される可能性があるため、メニューで選択されたすべての可能なアクションの後、ほとんどどこにでもバッファリングを追加することになります。

「オブザーバー」アプローチの代わりに、「mark-dirty」アプローチを使用して、変更されたインスタンスのみをマークし、アクションの最後にユーザー インターフェイスにそれ自体を更新するように指示することもできます。

繰り返しになりますが、ビジネス ロジックはアプリケーション内のどこからでも実行される可能性があるため、実際には、ユーザーが実行するほぼすべてのアクションの後に、追加の呼び出し (すべてのウィンドウに自分自身を更新する必要があることを伝える) を追加する必要がある場合があります。

両方のアプローチには似ているように見えますが、反対の欠点があります。

  • 「オブザーバー」アプローチでは、ユーザー インターフェイスを何度も更新するリスクがあります。
  • 「mark-dirty」アプローチでは、ユーザー インターフェイスをまったく更新しないというリスクがあります。

両方の欠点は、すべてのアプリケーション アクションを追加のロジックに埋め込むことで解決できます (オブザーバーの場合: 開始終了通知の送信、マークダーティの場合: update-yourself 通知の送信)。

非ウィンドウ アプリケーションでは、これはおそらく問題にならないことに注意してください。たとえば、mark-dirty アプローチを使用して、一部の計算でデータが必要な場合にのみ、データがダーティな場合に備えて追加の処理を行う必要がある場合があります (これは一種のキャッシュ アプローチです)。

ただし、ウィンドウ アプリケーションの場合、ユーザーが「画面を見ている」こと、およびウィンドウを更新する必要があることを示す信号はありません。そのため、ダーティ データを確認しなければならない、本当に良い瞬間はありません (ただし、フォーカス イベントを使用していくつかのトリックを行うことはできます)。

この問題を解決するための良い解決策は何ですか? また、アプリケーションでこのような問題をどのように解決しましたか?

アプリケーションの計算/データモデル部分にウィンドウ処理手法を導入したくないことに注意してください。この問題を解決するためにウィンドウ技術が必要な場合は、アプリケーションのユーザー インターフェイス部分でのみ使用する必要があります。

何か案が?

4

3 に答える 3

2

私が使用したアプローチは、数年前の大規模な Windows アプリで、WM_KICKIDLE. 更新可能なものはすべて、 と呼ばれる抽象基本クラスを利用しIdleTargetます。次にIdleTargetManager、メッセージをインターセプトし、KICKIDLE登録済みクライアントのリストで更新を呼び出します。あなたのインスタンスでは、更新する特定のターゲットのリストを作成できましたが、登録されたクライアントのリストで十分であることがわかりました。

私がヒットした唯一の問題は、リアルタイム グラフでした。キック アイドル メッセージだけを使用すると、グラフが絶えず更新されるため、CPU が 100% に急上昇します。タイマーを使用して、次の更新でその問題が解決されるまでスリープします。

さらにサポートが必要な場合は、リーズナブルな料金でご利用いただけます...:-)

于 2010-09-08T12:31:28.677 に答える
0

もう一つ気になった点。

生成されたイベントの数に圧倒され、それによって余分な作業が発生する可能性がある場合は、次の 2 つのフェーズのアプローチを使用できます。

  • 仕事をする
  • 専念

通知はコミット時にのみ送信されます。

一部のコードを強制的に書き直さなければならないという欠点があります...

于 2010-09-08T13:36:55.400 に答える
0

合体でオブザーバーパターンを使用できます。ただし、C++ で実装するのは少し見にくいかもしれません。次のようになります。

m_observerList.beginCoalescing();
m_observerList.notify();
m_observerList.notify();
m_observerList.notify();
m_observerList.endCoalescing(); //observers are notified here, only once

したがって、notify3 回呼び出しても、オブザーバーが 1 回だけ通知されるまで、オブザーバーは実際には通知されませんendCoalescing

于 2010-09-08T14:06:06.160 に答える