2012-07-05 6 views
6

私はCQRSデザインアプローチ(パターンとアーキテクチャ)を学び、新しいプロジェクトに適用しようとしていますが、欠けているようです。CQRSクライアントアプリケーションでUIリフレッシュを引き起こす要因は何ですか?

私のクライアントアプリケーションはクエリを実行し、読み取りモデルから軽量の読み取り専用DTOのリストを取得します。ユーザはアイテムを選択し、ボタンをクリックして何らかのアクションを開始する。アクションは、対応するコマンドオブジェクトを作成して書き込みモデルに送信することによって実行されます(コマンドハンドラがアクションを実行し、データストアを更新するなど)。しかし、ある時点で、UIを更新してアクションの結果としてのアプリケーションの状態。

元のリストを更新する時期はどのようになっていますか?

追加情報

私はCQRSを議論するほとんどの記事/ブログが彼らの例ではMVCのクライアントアプリケーションを使用していることに気づきました。私は今、Silverlightクライアントで作業しています。この場合、パターンが単純に機能しないかどうか疑問に思っています。

フォローアップの質問

パルトロミエの反応とその後の議論の詳細について考えた後、私はCQRSでのエラー処理について疑問に思って。コマンドは基本的には非同期操作であることを考えると、エラー状態をUIにどのように報告するのでしょうか?

私は2つの形式のいずれかを取るために「UIをリフレッシュ」を参照

  1. 操作が失敗した操作が成功し、データが変更されたとUIは、これらの変更
  2. を反映するように更新する必要があり、データを持っています変更されていないが、ユーザーには、障害と潜在的な是正措置が通知されるべきである。

MVCのPost-Redirect-Getパターンであっても、操作の結果を知るまで、本当にリダイレクトすることはできません。私がこれまで見てきた例では、これらの現実の懸念事項に対処していません。

私は、ユースケースに応じて、2つの技術を使用私のASP.NET MVC 3では

答えて

4

I WPFクライアントにとっても同様の問題を抱えています。すべてのデータの再クエリトリガーは、データあなたの更新に依存して、コマンドをカテゴリに陥る傾向がある:

  1. コマンドが真の火災で、方法を忘れて、それが状態変化のバックエンドに通知しますこの変更はUIに反映される必要はありません。変更は単にUIにとって重要ではありません。

  2. コマンドは

  3. コマンドは、カスケード方式で(少なくとも私のドメインに)通常、複数のクエリの結果が変更されます、それはの状態を変更、ある単一のクエリの結果を変更します単一の「高レベル」データが多くの「低レベル」キャッシュに影響する可能性があります。

私の最初のトリガは、ほとんどのページが最後に訪問したため、データが更新されたと仮定しなければならないとして、非常にいくつかの項目は、この免除され、ページのロードです。このようにして、財務やその他の重要なデータを更新するだけでは、システムによっては逃げ出すことができます。

短いコマンドでは、コマンドから「成功」が返されたときにデータを更新します。 IMHOのように、これは主に怠惰ですが、すべてのCQRSコマンドを非同期で起動する必要があります。これはまだ私が生きていけないオプションですが、インプリメンテーションでコマンドとクエリの待ち時間が長くなることが予想される場合には必要なものです。

1つのパターン私はメディエーター(ほとんどのMVVMフレームワークには1つが付属しています)を使用し始めています。私はコマンドを発射すると、起動されたコマンドを指定するメディエータにもメッセージを発します。各キャッシュ(ビューモデルのプロパティーRetriever<T>)は、それに影響を与えるコマンドをリッスンし、適切に更新します。私はメッセージの数を最小限に抑えながら、1つのメッセージから不必要に更新するキャッシュの数を最小限に抑えようとしていますので、最終的には更新理由の候補リストに終わります。

もう1つのアプローチは簡単な正直です。私は、システムの更新自体をグラフィカルに公開することで、ユーザーがそれに喜んで喜んで対応できるようになります。コマンドを起動すると、成功したレスポンスを待っていることを示すUIが表示されます。エラーが発生した場合は、エラーを再試行/表示することができます。成功すると、関連フィールドの更新が開始されます。このコマンドは他の端末(あなたが知りません)から起動された可能性があるので、他のマシンからも呼び出された状態の変更が失われるのを避けるために、データは最終的にタイムアウトする必要があります。

クライアントでキャッシュと値を更新する唯一の効率的な方法は、ハードコードやハッシュマップのようなもので、コマンドやクエリを再度分離しないことです。

+0

元の投稿から来ていたのと同じ考え方に近いような素晴らしいサマリーと聞こえます。私はドメイン・イベントを使用して合格/不合格を伝えないようにし、タスク・パラレル・ライブラリー(TPL)を活用して非同期性を維持しながら自分のニーズに対応しました。私の場合、コマンドバスにメッセージを送信すると、私はそのタスクに戻ります。これにより、非同期操作が完了したときに通知を受け取ることができ、例外を呼び出しコードに戻すことができます。これで、タスクの継続中のデータを簡単に更新できます。 – SonOfPirate

+0

私はこれがCQRSと一貫していると信じています。なぜなら、コマンドとクエリは依然として分離されていますが、あなたが言ったように、UIが望ましい/期待どおりに機能するならば、 – SonOfPirate

+0

さらに、これはMVVMにうまく収まります! – SonOfPirate

1

  • CQRSとうまくフィットし、既によく知られているポストリダイレクト-取得パターンを。コマンドをトリガするMVCアクションは、クエリを実行するアクションへのリダイレクトを返します。
  • 他のクライアントのリアルタイム更新のように、私はドメインのイベント/メッセージに依存しています。私は、singlarRを使用して、接続された、関心のあるすべてのクライアントに変更をプッシュするイベントハンドラを作成します。ユーザーはすぐにその変更を確認しないように

    1)、あなたのUIを設計:

+0

これは、私が見たすべてのCQRSの例がMVCクライアントを使用する理由を説明するかもしれません。残念ながら、私はSilverlightで作業しています(近い将来WPFに切り替える可能性があります)。そのアプローチはそこでは機能しません。しかし、私はASP.NET MVCを使って次回は良い情報があります。 – SonOfPirate

+0

正方形のペグ(CQRS)を丸穴(Silverlight)に押し込もうとしていますか? – SonOfPirate

+0

SilverlightアプリケーションでMVVMパターンを使用していますか? –

0

あなたは私の知る限り取ることができる2つの主要な方法があります。例えば、彼の行動を伝えるメッセージは成功であり、彼は仕事を続けるためにさまざまな選択肢を提供します。これはあなたにあなたのreadmodelを更新するのに十分な時間を買うべきです。

2)もっと複雑ですが、送信した情報をサーバーに保存して、それらをインターフェイスに表示することがあります。

私が思うよりも重要なのは、データがここにない理由を知るようにすることができれば、あなたのユーザーに教えてください...まだ!

私は今それについて考えていますが、これらは、syncコマンドの処理ではなく、非同期のためのものである、非同期のものでは脳に本当に難しい行く...クライアント・インターフェースは、あまりにもイベントイーターなり..

2

私の2セントです。

私はMVVMが実際にはCQRSによく似ていると思います。 ViewModelは、単に観察可能なReadModelになります。

1 - ReadModelのクエリを使用してViewModel状態を初期化します。

2 - ViewModelの変更は、それにバインドされているビューに自動的に反映されます。

3 - ViewModelの特定の変更により、メッセージキューにプロクエートするコマンドがトリガされます。これらのコマンドをサーバーに送信するオブジェクトは、キューからメッセージを取り出してWriteModelに送信します。

4 - クライアントが適切に構成されている必要があります。つまり、ViewModelがコマンドをトリガする前に適切な検証を実行している必要があります。コマンドがトリガーされると、イベント通知をイベント・バスに公開してクライアントが他のViewModelまたはそれらの変更に関心のあるシステム内のコンポーネントへの変更を通知することができます。これらのイベントには、関連する情報が必要です。通常、これは、他のビューモデルが、検索する必要がある他のデータに依存しない限り、変更の結果として通常は読み込みモデルを再クエリする必要がないことを意味します。

5 - 他のクライアントがこのクライアントが知りたいと思う変更を加えたときに、リアルタイムプッシュ通知のためにサーバ上のメッセージバスに接続し、必要に応じてロングポーリングに落ちるオブジェクトがあります。これらのメッセージは、内部のメッセージバスに伝播され、クライアント上のコンポーネントが一緒に関連付けられます。

6 - 最後の部分は、クライアントが時折接続できるという事実です。これは、コマンドが失敗した唯一の理由である必要があります(クライアントが現時点でインターネットにアクセスできない)問題の通知。

+0

また、接続が失われている間にサーバーから伝播されるはずのイベントに関しては、時折接続されたクライアントを処理します(しばらくの間のみ切断された場合)。おそらく、クライアントがReadModelから完全に再初期化する必要がある一定の閾値が存在します。 –

+0

私はこの問題にも苦労しています。私はブラウザがサーバーにコマンドを送信することに完全に同意します(非同期または同期?正しい方法はわかりませんが、今のところ残しておきます)、サーバーはコマンドを消費して状態を変更し、変更されたイベントを発行します。変更を示す情報私の質問は、どのように私たちは、このイベントに興味を持っているいくつかのサーバーサイドのものとuiを変更するブラウザのjavascriptの両方で読むことができるこの変更されたイベントを設計することができますか? – Ron

+0

この変更されたイベントは、JSONを使用してサーバーに送信する必要があります。サーバーが必要とするアクションを実行するために必要なデータのみを保持する必要があります。私。オブジェクトの新しい状態、オブジェクトの元の状態がすでにサーバー上に存在するはずです。サーバーは、何らかの種類のUUIDを使用して状態を変更しているオブジェクトを照合できる必要があります。 –

関連する問題