GUI を書いているとき、私はよく次の問題に直面しました。モデルとコントローラーがあるとします。コントローラーには、モデルW
のプロパティを表示するために使用されるウィジェットがあります。X
モデルはコントローラーの外部から変更される可能性があるため (同じモデルを使用する他のコントローラーが存在する可能性があるため、元に戻す操作など)、コントローラーはモデルの変更をリッスンします。コントローラーはウィジェットのイベントもリッスンし、それに応じW
てプロパティを更新しますX
。
ここで、次のことが起こります。
- の値
W
が変更されます - イベントが生成され、コントローラーのハンドラーが呼び出されます
- コントローラーはモデルの新しい値を設定し
X
ます - モデルが変更されたため、モデルはイベントを発行します
- コントローラはモデルから変更イベントを受け取ります
- コントローラーは値を取得し、
X
ウィジェットに設定します - 1に行きます。
そのための解決策がいくつかあります。
- モデルが更新されたときにフラグを設定するようにコントローラーを変更し、このフラグが設定されている場合はモデルからのイベントに反応しないようにします。
- コントローラーを一時的に切断します (または、モデルにしばらくイベントを送信しないように指示します)。
- ウィジェットからの更新を凍結する
以前は、オプション 1. を選択していました。これが最も簡単だからです。クラスがフラグで雑然とするという欠点がありますが、他の方法にも欠点があります。
記録のために、GTK+、Qt、SWT などのいくつかの GUI ツールキットでこの問題が発生したので、ツールキットに依存しない問題だと思います。
ベストプラクティスはありますか? それとも、私が使用しているアーキテクチャが単に間違っているのでしょうか?
@Shy: これは場合によっては解決策ですがX
、コントローラーの外部から変更された場合 (たとえば、元に戻す/やり直しのコマンド パターンを使用する場合) は、値が変更され、W
更新されるため、余分なイベントのラウンドが発生します。そしてイベントを発生させます。モデルへの別の (無駄な) 更新を防ぐために、ウィジェットによって生成されたイベントを飲み込む必要があります。
他のケースでは、モデルがより複雑で、複雑なツリー ビューなど、何が正確に変更されたかを簡単に確認することができない場合があります。