最初の部分では、
Red Architectureの概念を紹介します。これは、複雑なシステム内のコンポーネント間の相互作用を単純化するアプローチであり、主にクライアントアプリケーションを対象としています。 現在の記事を完全に理解するには、
ここでこの概念を理解する必要があり
ます 。
最初の部分への最近のコメントの追跡に従って、重要でないタスクを解決するためのRed Architectureの使用を示す完成した例を検討します。
クライアントアプリケーションがあります-テーブルエディター、テーブルシートが表示されます。 ユーザーの画面は非常に大きいため、1,000,000,000(10億)のテーブルセルが含まれています。 表の共同編集の可能性のためにスプレッドシートエディタがクラウドに接続されているという事実により、すべてが複雑になります。そのため、「クラウド内のどこか」の10億個のセルの変更はすぐにユーザーに表示されます。Red Architectureパターンを使用すると、この機能を簡単かつ高性能で実装できます。
まず、クラスvを少し改良する必要があります10億個のセルのそれぞれが、受信した各イベントを自分自身とのコンプライアンスをチェックするオプションは適切ではありません。 ハンドラー関数への10億回の呼び出し+ 1つのセルが変更されるたびに10億回のGUIDの比較-これは、ハイエンドユーザーデバイスには多すぎます。
この問題の解決策を検討してください。
これで、クラス
vのキー(論理チェーンを識別する)は列挙要素ではなく、文字列になります。 簡潔さと簡単な認識の
ために、疑似コードで記述します:
class v {
実際にフォーマット文字列であるキーを宣言しますか? 実際には、どのような場合でも、セルは表形式シートで何らかの方法で識別される必要があります。 「クラウドから」来たセル更新情報には、シート名(List1)やセルアドレス(D9)など、セルを識別するデータが含まれていると仮定します(そうでなければ、更新するシートでそれを見つける方法は?)。 また、ユーザーの画面に表示される各セルは、それ自体へのパス、つまり同じシート名とそのアドレスを「知っている」と仮定します(そうでない場合、システムに変更が発生したことを通知します。他に何か?)。
次に、
h()メソッドに別の引数を追加する必要があります。 現在、ハンドラーはシステム内のすべてのキーではなく、最初の引数として渡される特定のキーをサブスクライブします。
class v {
ハンドラーを格納するには、1対多のペアを含むHashMap型のプライベートコレクションを使用します。1つ以上のハンドラーがサブスクライブできる1つのキー。 そして、サブスクライバーによってイベントを「ディスパッチ」する
Add()メソッドでは、このキーにサブスクライブされたハンドラー関数のみを使用します。 潜在的な10億個の要素を持つコンテナの場合、そのようなデータボリュームに適した実装を見つけることは価値があるため、文字列キーを暗黙的に数値ハッシュ値に変換するコレクションであるHashMapを使用します。 10億個の要素の場合、HashMapを使用すると、30を超えない数の比較操作で、バイナリ検索によって目的の要素を見つけることができます。 このようなタスクは、性能の低い機器でもほぼ瞬時に実行されます。
以上です! ここで、Red Architecutreの「インフラストラクチャ」、つまりクラスvの変更が終わりました。 そして、セルの更新を受信して表示するロジックを検討し始めることができます。
最初に、更新を受け取るためにセルを登録する必要があります。 セル登録コードは、
OnAppear()メソッドで提供されます。
class TableCellView {
OnAppear()メソッドで画面にセルが表示されると、オブジェクトのコンストラクターで生成され、後でこのセルにデータを転送できる形式キー
文字列v.OnCellUpdateから派生した一意のキー
thisCellUpdateKeyでイベントを受け取るために「登録」します。他のセルで関数ハンドラーを呼び出さずに。
OnEvent()ハンドラーメソッドでは、現在のセルに一致するキーをチェックします(実際、
OnCellUpdateの場合、このチェックは必要ありませんが、ハンドラーで複数のキーを処理できるため、それでも望ましいです)。現在のセルは表示データを更新します
this.CellContent = data.Content;次に、セルへのデータの送受信のロジックを検討しますセルの更新に関する情報が、ソケットを介して「クラウド」から送られてきたとします。 この場合、セルへのデータの送受信のロジックは次のようになります。
class SomeObjectWorkingWithSocket { void socket.OnData(data) { if(data.Action == SocketActions.UpdateCell) { string cellKey = string.Format( v.OnCellUpdate, data.List, data.Address); v.Add(cellKey, data);
したがって、1回の呼び出し(特定の論理チェーンに適用されないクラスv内のロジックはカウントしません)で、データを受信場所から使用場所に10億の特定のセルに転送しました。 論理チェーン全体には、数行のコードと、この関数に関連付けられているすべてのコードを含む1つの
OnCellUpdateキーがあります。
新しい開発者が私たちのチームに来て、彼の最初のタスクが何らかの方法でセルの更新をアニメートすることを想像してください、または、例えば、セルを更新するとき、新しいデータだけでなく、変更の日付/時刻も表示します。
彼にとってどれほど難しいかを理解するために、いくつかの質問に答えてみます。
- この問題を解決するために「パッチを当てる」必要があるコードを見つけるのにどれくらい時間がかかりますか? -すべての関連コードは即座に見つけることができます。主なことは、開発者にv.OnCellUpdateコードで検索するように指示することです。
- 私たちの場合、そのようなタスクにどれくらいの時間がかかりますか? -表示とアニメーションの問題を解決するために既存のAPIをうまく利用できれば、1〜2日で十分です。
- 新しい開発者が何か間違ったことをしなければならない可能性はいくつありますか? -十分ではありません:コードはシンプルで、簡単に把握できます。
概略的に、v.OnCellUpdateキーのデータチェーンは次のとおりです。

これは終了する可能性がありますが...タスクが表示されただけでなく、受信したデータをキャッシュするようになりました。 すでに書かれているものを変更する必要がありますか、さらに悪いことに、すべてを書き換える必要がありますか? いや!
Red Architectureでは、オブジェクトは互いに完全に無関係です。 タスクが来ました-関数を追加するには、この形式でこのタスクがコードに反映されます-既に書き込まれた内容を変更せずにデータをキャッシュするコードを追加します。 すなわち:
class db { handler void OnEvent(string key, object data) { if(key == v.OnUpdateCell)
セルの更新に関連付けられたすべてのロジックは、マッピングまたはキャッシュに関係なく、依然としてシンプルであり、v.OnUpdateCellキーによってコード内で識別されます。
2番目の部分、最初の部分を
ここで読み
ます 。
3つのパートで、マルチスレッドの問題を解決します。