web-dev-qa-db-ja.com

JSFバッキングBean構造(ベストプラクティス)

この投稿で、JSFページとバッキングBean間のインターフェースのベストプラクティスに関する意見を得ることができれば幸いです。

私が決して解決できないことの1つは、バッキングBeanの構造です。さらに、このテーマに関する良い記事を見つけたことがありません。

どのプロパティがどのバッキングBeanに属しますか?新しいBeanを作成してプロパティを追加するのではなく、特定のBeanにさらにプロパティを追加するのが適切な場合単純なアプリケーションの場合、あるBeanを別のBeanに注入することに伴う複雑さを考慮して、ページ全体に対して単一のバッキングBeanを用意するのが理にかなっていますか?バッキングBeanには実際のビジネスロジックを含める必要がありますか、それとも厳密にデータを含める必要がありますか?

これらの質問やその他の質問に自由に答えてください。


JSFページとバッキングBeanの間の結合を減らすことに関して、JSFページがバッキングBeanプロパティのプロパティにアクセスすることを許可しません。たとえば、次のようなことは許可しません。

<h:outputText value="#{myBean.anObject.anObjectProperty}" />

私は常に次のようなものが必要です:

<h:outputText value="#{myBean.theObjectProperty}" />

バッキングBeanの値は次のとおりです。

public String getTheObjectProperty()
{
    return anObject.getAnObjectProperty();
}

コレクションをループするときは、ラッパークラスを使用して、たとえばデータテーブル内のオブジェクトにドリルダウンしないようにします。

一般的に、このアプローチは私にとって「正しい」と感じています。ビューとデータ間のカップリングを回避します。私が間違っている場合は修正してください。

116
Zack Marrapese

これを確認することをお勧めします: 異なる種類のJSF管理対象Beanを区別する

Neil Griffinによる上記の記事で定義されている、さまざまなBeanタイプの説明を次に示します。

  • モデルマネージドBean通常はセッションスコープ。このタイプのマネージドBeanは、「モデル」の懸念事項に関与します。 MVCデザインパターンの。 「モデル」という言葉が表示されたら、データを考えてください。 JSFモデルBeanは、プロパティをカプセル化するゲッター/セッターを持つJavaBeanデザインパターンに従うPOJOである必要があります。モデルBeanの最も一般的な使用例は、データベースエンティティにすること、またはデータベースクエリの結果セットから行セットを単純に表すことです。
  • マネージドBeanのバッキング通常リクエストスコープ。このタイプのマネージドBeanは「ビュー」の懸念に関与しますMVCデザインパターンの。バッキングBeanの目的はUIロジックをサポートすることであり、JSFビューまたはFaceletコンポジションのJSFフォームと1 :: 1の関係があります。通常、関連するゲッター/セッターを持つJavaBeanスタイルのプロパティがありますが、これらはビューのプロパティであり、基礎となるアプリケーションデータモデルのプロパティではありません。 JSFバッキングBeanには、JSF actionListenerおよびvalueChangeListenerメソッドも含まれる場合があります。
  • Controller Managed-Bean通常はスコープをリクエストします。このタイプのManaged-Beanは「Controller」の懸念事項に関与しますMVCデザインパターンの。コントローラーBeanの目的は、ある種のビジネスロジックを実行し、ナビゲーションの結果をJSFナビゲーションハンドラーに返すことです。 JSFコントローラーBeanには通常、JSFアクションメソッドがあります(actionListenerメソッドはありません)。
  • マネージドBeanのサポート通常、セッションまたはアプリケーションのスコープ。このタイプのBeanは、1つ以上のビューを「サポート」します。 MVC設計パターンの「表示」に関する懸念。典型的な使用例は、複数のJSFビューに表示されるJSF h:selectOneMenuドロップダウンリストにArrayListを提供することです。ドロップダウンリストのデータがユーザー固有のものである場合、Beanはセッションスコープに保持されます。ただし、データがすべてのユーザー(州のドロップダウンリストなど)に適用される場合、Beanはすべてのユーザーに対してキャッシュできるようにアプリケーションスコープに保持されます。
  • ユーティリティマネージドBean通常はアプリケーションスコープ。このタイプのBeanは、何らかのタイプの「ユーティリティ」機能を提供します。 1つ以上のJSFビュー。これの良い例は、複数のWebアプリケーションで再利用できるFileUpload Beanです。
144
Paul Rivera

いい質問ですね。 JSFに移行したとき、私は同じジレンマに苦しみました。それは本当にあなたのアプリケーションに依存します。私はJava EEの世界から来ているので、バッキングBeanにできる限り少ないビジネスロジックを含めることをお勧めします。ロジックがページの表示に純粋に関連している場合バッキングビーンに入れても大丈夫です。

JSFの(多くの)強みの1つは、実際には管理対象Beanでドメインオブジェクトを直接公開できるという事実です。したがって、<:outputText value="#{myBean.anObject.anObjectProperty}" />アプローチ、それ以外の場合は、各プロパティを手動で公開するために自分自身のためにあまりにも多くの作業を行うことになります。さらに、すべてのプロパティをカプセル化すると、データを挿入または更新するときに少し混乱します。単一のドメインオブジェクトでは不十分な場合があります。そのような場合、Beanに公開する前にValueObjectを準備します。

編集:実際、公開するすべてのオブジェクトプロパティをカプセル化する場合は、代わりにUIコンポーネントをバッキングBeanにバインドし、コンポーネントの値にコンテンツを直接挿入することをお勧めします。

Bean構造に関して、私にとってのターニングポイントは、Webアプリケーションの構築について知っているすべてのものを強制的に無視し、代わりにGUIアプリケーションとして扱うようになったことです。 JSFはSwingをよく模倣しているため、Swingアプリケーションを開発するためのベストプラクティスは、JSFアプリケーションの構築にもほとんど適用されます。

バッキングBeanで最も重要なことは、ロジックを分離することだと思います。 CMSシステムのフロントページがある場合、すべてのコードを1つのBeanに入れるのは悪い習慣だと思います。

  1. 豆は最終的に非常に大きくなります
  2. 他の人がログインページのトラブルシューティングをしている場合、loginBean.Javaファイルを簡単に調べることができれば、探しているものを簡単に見つけることができます。
  3. ときどき、コードの残りの部分とは明確に区別される小さな機能があります。これを分離することにより、すでに良いBeanが既にあるときに、このコードをより大きなものに再開発/拡張することが容易になると思います構造。
  4. すべてを行うために1つの大きなBeanを使用すると、次のような宣言を行う必要がある場合に、メモリーに依存するようになります。BigBean bigBean = new MyBigBean(); LoginBeanを実行して実際に必要なfunksjonalityを使用する代わりに、loginBean = new LoginBean(); (私がここで間違っている場合は私を修正してください???)
  5. 私の意見では、Beanの分離はメソッドの分離に似ています。 100行を超える1つの大きなメソッドが必要なわけではありませんが、特定のタスクを処理する新しいメソッドで分割します。
  6. おそらく、あなた以外の誰かがあなたのJSFプロジェクトにも取り組む必要があることを忘れないでください。

質問にすでに回答済みとマークされている場合でも、これに関する私の2セントです。

4
Chris Dale

ケースバイケースに非常に依存しているように思われるので、私はあなたのすべての質問に答えないかもしれません。

  • これは、バッキングBeanにビジネスロジックを含めるには問題ありません。どこから来ているかによります。ドメイン駆動型の設計を実践している場合は、バッキングBeanにビジネスロジックを含めるように誘惑されるか、永続ロジックである場合もあります。彼らは、なぜそんなに物の言えないオブジェクトであると主張します。オブジェクトは、状態だけでなく動作も保持する必要があります。一方、従来のJava EEのやり方を検討する場合、バッキングBean(エンティティBean、その他のビジネスおよび永続ロジックでも可)にデータがあるように感じるかもしれません一部のセッションBeanなどで使用できます。

  • ページ全体で単一のバッキングBeanを使用してもまったく問題ありません。これだけで問題は見られません。これは正しく見えないかもしれませんが、それは場合によって異なります。

  • 他の質問は、手元にあるケースにはるかに依存しています。ここでドメインドリブンに移行したい場合は、既存のプロパティを追加するか、そのための新しいBeanを作成するのが適切かもしれません。どちらがより適しています。これに特効薬はないと思います。

  • どのプロパティがどのバッキングBeanに属します。まあ、それはドメインオブジェクトに依存していませんか?または、質問はそれほど明確ではないかもしれません。

さらに、指定されたコード例では、大きな利点は見当たりません。

4
Adeel Ansari

ページごとにバッキングBeanを1つだけ保持する必要はありません。機能に依存しますが、ほとんどの場合、1ページで1つの機能を処理するため、ページごとに1つのBeanがありました。たとえば、ページには登録リンク(RegisterBeanとリンクします)と買い物かごリンク(ShoopingBasketBean)があります。

通常、データオブジェクトを保持するアクションBeanとしてBeanをバッキングしているため、この<:outputText value = "#{myBean.anObject.anObjectProperty}" />を使用します。データオブジェクトのプロパティにアクセスするために、バッキングBeanにラッパーを記述したくありません。

4

私はViewなしでビジネスコードをテストするのが好きなので、BackingBeansをViewからModelコードへのインターフェースと考えています。 BackingBeanにルールやプロセスを配置することはありません。そのコードはサービスまたはヘルパーに渡され、再利用が可能になります。

バリデーターを使用する場合、それらをBackingBeanから取り出して、検証メソッドから参照します。

Select、Radio、Checkboxを埋めるためにDAOにアクセスする場合は、常にBackingBeanからそれを行います。

私を信じてください!。 JavaBeanをBackingBeanに注入できますが、BackingBeanを別のBeanに注入しようとします。すぐにメンテナンスとコードの理解が無制限になります。

0
jjruiz