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


118

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

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

どのバッキングBeanにどのプロパティが属していますか?新しいBeanを作成してプロパティを追加するのではなく、特定のBeanにプロパティを追加するのが適切な場合はいつですか。単純なアプリケーションの場合、1つの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();
}

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

一般的に、このアプローチは私にとって「正しい」と感じています。ビューとデータの間の結合を回避します。私が間違っていたら訂正してください。


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

2
詳細については、でBalusCの回答を参照してくださいstackoverflow.com/questions/7223055/...
ザックMarrapese

回答:


146

これを調べてみてください。さまざまな種類のJSF管理対象Beanを区別します

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

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

8
これは素晴らしい記事です。私はこれまでに見たことがないので、あなたが投稿してくれて本当にうれしいです。これに反対票を投じた人は誰でもクレイジーです。iceFaces固有ではありません。
ザックマラピーゼ2009年

2
実際の記事へのリンクがなくなっているようです。
Bill Rosmus、2012


10
それでも、この回答が現在71票であるとは言えません。これらのルールに従ってJSFアプリケーションを実装した人は誰でも、間違いなくJSFがひどく不透明なフレームワークであり、そのJSFアプリケーションが大きなコードの混乱であることを認め、間違いのあるレッスンに基づく独自の悪いアプローチではなくJSF自体を非難し、いわゆる「ベストプラクティス」を学びました。
BalusC 2013

これらのBeanのロジックはサーバーではなくブラウザで実行されますか?
eskalera 2014

14

すばらしい質問です。私がJSFに引っ越したとき、私は同じジレンマでたくさん苦しみました。それは本当にあなたのアプリケーションに依存します。私はJava EEの世界の出身なので、バッキングBeanのビジネスロジックをできるだけ少なくすることをお勧めします。ロジックがページの表示にのみ関連している場合は、バッキングBeanに含めても問題ありません。

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

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

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


あなたの洞察をありがとう。Swingアプリケーションの方法で実際に多くのことをしたことはありません(昔の学術プロジェクトを除いて)。Swingアプリケーションのいくつかの良い原則は何ですか?また、値を挿入および更新するときに混乱するのはなぜですか?私にも同じように見えますか?
Zack Marrapese、2009

5

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

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


カップリングに関しては、JSFページがバッキングBean内のオブジェクトのプロパティにもアクセスできるようにするのは厄介な問題とは思いません。これは、JSFに組み込まれているサポートであり、本当にimoの読み取りとビルドを簡単にするだけです。MVCロジックを完全に分離するあなたのすべて。これを行うことで、backingbeanでゲッターとセッターを使用して大量の行を節約できます。たとえば、プレゼンテーションでいくつかのプロパティを使用する必要があるWebサービスから非常に大きなオブジェクトが提供されています。プロパティごとにゲッター/セッターを作成する場合、私のBeanは、プロパティを取得するための変数とメソッドの少なくとも100行以上で拡張されます。組み込みのJSF機能を使用することで、時間と貴重なコード行を節約できます。

すでに回答済みとマークされている質問があったとしても、これについてはちょうど私の2セントです。


1
ただし、Bean内に巨大なオブジェクトがあり、JSFページからそのオブジェクトを掘り下げる15のEL関数がある場合、Beanだけでなくそのオブジェクトにも関連付けられます。したがって、UIを壊さずにそのオブジェクトを削除することは困難です。
Zack Marrapese、2009

1
しかし、バッキングBeanもそのオブジェクトに関連付けられていませんか?そしてあなたのUIはバッキングBeanに関連付けられていますか?その後、変更する必要がある場合は、UIとBeanの両方ですべてのゲッター/セッターを変更する必要があります。
Chris Dale、

4

ケースごとにかなり依存しているように見えるので、私はあなたのすべての質問に答えないかもしれません。

  • バッキングBeanにビジネスロジックを含めることは問題ありません。どこから来たのかによります。ドメイン主導の設計を実践している場合、ビジネスロジックをバッキングBeanに含めたくなったり、永続化ロジックになったりする可能性があります。彼らは、なぜそんなに馬鹿げたオブジェクトなのかと主張している。オブジェクトは状態だけでなく動作も運ぶ必要があります。一方、従来のJava EEの方法を検討すると、バッキングBean(エンティティBeanにもなる可能性があります)や、セッションBeanなどのその他のビジネスおよび永続化ロジックにデータがあるように感じるかもしれません。それも結構です。

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

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

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

さらに、あなたが与えられたコード例では、私は大きな利益を見ていません。


たとえば、JDBCクエリで作成された自家製のPOJOの使用から、フィールド名がわずかに異なるHibernateエンティティに変更する場合、バッキングBeanを変更するだけでなく、JSFページも変更する必要があります。私のコード例ではそうではありません。豆を変えるだけ。
Zack Marrapese

その場合、バッキングBean、エンティティを作成できます。次に、JSFページを変更するだけです。それとも、とにかくプロパティの名前を変更する理由に依存しますか?これは、データベースの列名と一致するようにフィールドの名前を変更した場合にのみ意味があります。しかし、それはまったく別のケースです。
Adeel Ansari、

4

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

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


0

私はビューを使用せずにビジネスコードをテストするのが好きなので、BackingBeansをビューからモデルコードへのインターフェースと見なします。私はBackingBeanにルールやプロセスを入れたことはありません。そのコードはサービスまたはヘルパーに送られ、再利用が可能になります。

バリデーターを使用する場合は、それらをBackingBeanの外に置き、検証メソッドから参照します。

選択、ラジオ、チェックボックスを埋めるためにDAOにアクセスする場合は、常にBackingBeanから実行してください。

私を信じてください!。JavaBeanをBackingBeanに注入できますが、BackingBeanを別のJavaBeanに注入してみてください。間もなく、保守とコードの理解が困難になります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.