大規模な製品での「ほとんどプル」アプローチの経験:
モデル:ノードは1:Nツリーを構築します。つまり、各コンポーネント(ルートを除く)には1つの親と1..Nの子があります。データはほとんど親から子に流れます。変更通知は、ツリー内の任意のノードから発信できます。
実装:すべてのリーフは、送信ノードのIDと「生成」カウンターで通知されます。リーフは、依存しているノードパスを知っているため、更新する必要があるかどうかを知っています。(他の子ノード更新アルゴリズムも同様に機能し、後から考えるとより優れている可能性があります)。
Leafsは親に現在のデータを照会し、照会は再帰的にバブルアップします。生成カウンターが含まれているため、バブルアップは元のノードで停止します。
利点:
- 親ノードは、子に関する多くの/情報を必要としません。データは誰でも消費できます-これにより、表示を目的としたデータに加えて、いくつかの(当初は予期されていなかった)非UI機能を実装するための一般的なアプローチが可能になりました
- 子ノードは更新を集約して遅延させることができます(再描画を回避することで、高速ペイントよりも確実に優れています)
- 非アクティブなリーフは、データトラフィックをまったく発生させません
短所:
- 完全なデータが公開されるため、増分更新にはコストがかかります。実装では、実際にはさまざまなデータパケットを要求できますが(生成カウンターは不要なデータトラフィックを防ぐことができます)、最初に設計されたデータパケットは非常に大きくなります。それらをスライスすることは後付けでしたが、問題なく機能します。
- 本当に良い生成メカニズムが必要です。最初に実装されたものは、初期更新(特別な処理が必要-「増分更新」を参照)および更新の集約と衝突しました
- ツリーを上るデータの必要性は大幅に過小評価されていました。
- 公開は、ノードが現在のデータへの読み取り専用アクセスを提供する場合にのみ安価です。ただし、これには追加の更新同期が必要になる場合があります
- すべてのリーフが非アクティブな場合でも、中間ノードを更新したい場合があります
- 一部のリーフはポーリングを実装することになり、一部のベースノードはそれに依存することになりました。ぶさいくな。
一般的:
データプルは、データと処理レイヤーがUIについて何も知らないはずのときに、私にとってよりネイティブな感じがします。ただし、「ユニバースの更新」を回避するには、複雑な変更通知メカニズムが必要です。
データプッシュは増分更新を簡素化しますが、送信者が受信者をよく知っている場合に限ります。
他のモデルを使った同様のスケールの経験がないので、私は本当に推薦することができません。振り返ってみると、私は主にプルを使用していたことがわかりますが、これはそれほど面倒ではありませんでした。他の人々の経験を見るのは興味深いでしょう。