1

できるだけ簡潔にしようと思います。アプリにFlex/Hibernateテクノロジーを使用しています。FlexにはCairngormマイクロアーキテクチャも使用しています。私は初心者なので、CaringormのModelLocatorの目的について何か誤解している可能性があります。次の問題があります...

次のデータモデルがあるとします。

USER  ---------------->  TOPIC  ------------->  COMMENT     
      1              M          1           M 

ユーザーは多くのトピックを開始でき、トピックには多くのコメントを含めることができます。たとえば、これは非常に単純なモデルです。Hibernateでは、単方向のUSER->TOPICおよびTOPIC->COMMENT関係にEAGERフェッチ戦略を使用します(ここでは、ベストプラクティスなどについての質問はありません。これは、問題の単なる例です)。

私のModelLocatorは次のようになります。

...
public class ModelLocator  ....
{
    //private instance, private constructor, getInstance() etc...
    ...

    //app state
    public var users:ArrayCollection;
    public var selectedUser:UserVO;
    public var selectedTopic:TopicVO;
}

私は熱心なフェッチを使用しているため、データベースにアクセスすることなく、Flexクライアント上のすべてのオブジェクトグラフを「ウォークスルー」できます。一部のドメインインスタンスを挿入、更新、または削除する必要がない限り、これは問題ありません。しかし、それが発生すると、同期に関する問題が発生します。

たとえば、 UserListViewからユーザーの詳細を表示したい場合、user(actor)がリストでそのユーザーを選択すると、UserListで選択されたインデックスを取得し、ModelLocatorのusers ArrayCollectionから選択されたインデックスで要素を取得し、選択されたものの詳細を表示しますユーザー。

新しいユーザーを挿入したい場合は、OK 、そのユーザーをデータベースに保存し、IResponder結果メソッドでそのユーザーをModelLocator.usersArrayCollectionに追加します。

しかし、一部のユーザーに新しいトピックを追加したい場合、それでもEAGERフェッチの便利さを使用したい場合は、ユーザーリストを再度リロードする必要があります...そして選択したユーザーにトピックを追加するには...そしてユーザーが一部のユーザーにいる場合他の場所(間接的に)、私はそこにもトピックを挿入する必要があります。更新はさらに最悪です。その場合、私はいくつかのロジックを書く必要があります...

私の質問:CairngormでModelLocatorを使用するこの良い方法はありますか?言及されているため、EAGERフェッチはどういうわけか無意味であるように私には思えます。EAGERフェッチを使用する場合、Flexクライアントでの同期が大きな問題になる可能性があります。ドメインモデルを操作するには、常にデータベースにアクセスする必要がありますか?

編集: 私は自分自身を十分に明確にしなかったようです。すみません。

わかりました。テクノロジースタックでもSpringを使用し、フレックス/スプリング(デ)シリアライザーでDTO(DVO)パターンを使用していますが、データベースの状態との同期をどのように維持するかを指摘しようとしているので、それを避けたかったのです。フレックスアプリ。マルチユーザーシナリオやポーリング/プッシュのトピックについては触れていません。これは、標準の要求応答メカニズムを使用しているため、おそらく私の解決策です。これは私にとって概念的な問題のように思われるため、具体的なコードは提供しませんでした。クラス名や変数名などに使用する疑似名を説明するために、標準のCairngorm用語を使用しています。

もう一度「単純化」してみます。上記のドメインを管理するためのフレックスクライアント(各ドメインクラスのCRUD)、ListOfUsersView(ユーザーの基本情報を含むユーザーのリストを表示)、UserDetailsView(ユーザーの詳細と各トピックの削除オプションを含むユーザートピックのリスト)、InsertNewUserTopicView(新しいトピックを挿入するためのフォーム)など。

一部の情報を表示する各ビューは、ModelLocatorの状態変数と同期されます。次に例を示します。

ListOfUsersView ------binded to------> users:ArrayCollection in ModelLocator
UserDetailsView ------binded to------> selectedUser:UserVO in ModelLocator 
etc.

ビューステート遷移は次のようになります。

ListOfUsersView----detailsClick---->UserDetailsView---insertTopic--->InsertTopicView

したがって、ListOfUsersViewの[詳細]ボタンをクリックすると、ロジックで、 ListOfUsersで選択した行のインデックスを取得します。その後、ユーザーからUserVOオブジェクトを取得します。前述のインデックスでModelLocatorのArrayCollectionを取得し、その後、そのUserVOオブジェクトをselectedUserとして設定します。:ModelLocatorのUserVOとその後、ビューの状態をUserDetailsView(ユーザーの詳細とselectedUser.topicsが表示されます)に変更します。これは、ModelLocatorのselectedUser:UserVOと同期されます。

次に、 UserDetailsViewの[新しいトピックを挿入 ]ボタンをクリックすると、InsertTopicViewフォームが表示されます。データを入力し、[トピックの保存]をクリックします(保存が成功すると、UserDetailsViewが再度表示されます) 。問題が発生します。

EAGERでフェッチされたオブジェクトのため、前述の遷移でデータベースにアクセスしませんでした。そのため、選択したユーザーに新しいトピックを挿入するときに気にする必要がある場所が2つあります。1つはユーザー内のselectedUserオブジェクトのインスタンスです。 :ArrayCollection(私のロジックはそのコレクションからユーザーを選択してUserDetailsViewに表示するため)、2番目はselectedUser:UserVO(保存操作が成功した後に来るUserDetailsViewを同期するため)です。

したがって、再び私の質問が発生します...データベースの状態をフレックスクライアントと同期するために、保存後にusers:ArrayCollectionとselectedUser:UserVOをリロードする必要がありますか?データベースにアクセスし、プログラムで更新する必要のあるすべての場所を渡しますか...?

EAGERでフェッチされたオブジェクトとそれらの関連付けは適切ではないように思われます。私が間違っている?

または、「単純化」するために:)もう一度、前述のシナリオで何をする必要がありますか?だから、あなたは「トピックを保存」ボタンをクリックすることを処理する必要があります、そして今何...?

繰り返しますが、私はこれと混同しているので、これを可能な限りプラスチックとして説明しようとしています。だから、私の長いポストを許してください。

4

3 に答える 3

4

私の見解では、ポイントはフェッチモード自体ではなく、クライアント/サーバーの相互作用にあります。以前の経験から、クライアント/サーバーの相互作用に純粋なドメインオブジェクトを使用することのいくつかの欠点(特に熱心なフェッチ)を最終的に発見しました。

  • クライアント側で使用する必要がない場合は、すべての子コレクションを渡す必要があります。あなたの場合、サーバーから取得したすべてのユーザーに対してではなく、トピックやコメントを表示する可能性が非常に高くなります。最もよく似た状況では、ユーザーリストを表示してから、選択したユーザーの1人のトピックを表示してから、選択したトピックの1人のコメントを表示する必要があります。ただし、現在の実装では、表示する必要がない場合でも、すべてのトピックとコメントを受け取ります。1回のクエリですべてのDBを受け取る可能性が非常に高くなります。
  • もう1つの問題は、すべてのフィールド(電子メール、アドレス、パスワード、クレジットカード番号など)を含むすべてのユーザーデータ(またはその他のデータ)を取得することが非常に安全でない可能性があることです。

特に熱心なフェッチで純粋なドメインオブジェクトを使用しない理由は他にもあると思います。

ドメインオブジェクトをデータ転送オブジェクト(別名DTO)に変換するために、マッパー(またはアセンブラー)レイヤーを導入することをお勧めします。したがって、サービスレイヤーへのすべてのクエリは、DAOまたはActive Recordからデータを受信し、対応するMapperを使用して対応するDTOに変換します。したがって、プライベートデータなしでユーザーリストを取得し、別のクエリでいくつかの追加のユーザー詳細をクエリできます。

クライアント側では、これらのDTOを直接使用することも、クライアントドメインオブジェクトに変換することもできます。あなたはあなたのCairngormレスポンダーでそれをすることができます。

このようにして、説明したクライアント側の問題の多くを回避できます。

マッパーレイヤーの場合は、Dozerライブラリを使用するか、独自の軽量マッパーを作成できます。

お役に立てれば!

編集 あなたの詳細はどうですか私は(リストに表示するために)名や姓のような必要な表示可能なフィールドを持つユーザーリストを取得したいと思います。のリストを言いSimpleUserRepresentationDTOます。

次に、ユーザーが編集のためにユーザーの詳細を要求UserDetailsDTOした場合、そのユーザーを要求し、モデルのツアーselectedUserフィールドにそれを入力します。トピックについても同じです。

唯一の問題は、ユーザーの詳細を編集した後にユーザーのリストを表示することです。あなたはできる:

  • リスト全体をもう一度リクエストしてください。利点は、他のユーザーによって実行された変更を表示できることです。SimpleUserRepresentationDTOただし、リストが長すぎると、データが最小限であっても、毎回すべてのユーザーにクエリを実行するのは非常に効果的ではありません。
  • サーバーからユーザー詳細の保存に成功すると、モデルのユーザーリストで対応するユーザーを見つけて、そこで変更された詳細を置き換えることができます。
于 2011-05-26T19:13:38.610 に答える
0

「dpHibernate」プロジェクトを見てください。Flexクライアントに「遅延読み込み」を実装します。

于 2011-05-26T21:42:29.933 に答える
0

実を言うと、Cairngormを使用する良い方法はありません。それはがらくたフレームワークです。

熱心なフェッチが何を意味するのか(または正確に何が問題なのか)はよくわかりませんが、それが何であれ、それは要求/応答の種類の取引であり、あなたがそうでない限り、これは言うまでもなく問題にはなりません。何か正しいことをしていない。その場合、私はあなたのコードを見ることができません。

フレームワークについては、 RobotLegsまたはParsleyを参照することをお勧めします。

于 2011-05-26T18:37:06.523 に答える