it-swarm-ja.tech

複雑なEL式を単一のJavaBeanゲッターで置き換える必要がありますか?

JSFで、いくつかの変数に基づいて条件付きでレンダリングするコンポーネントがある場合、レンダーステートメントを処理するための最適な方法は何ですか。ロジックはコンポーネント宣言または何らかの形式のヘルパークラスに存在しますか

テキストwoofは、動物が象または犬であり、動物がミュートになっていない場合にのみ表示されます。

オプション1:

ビューでの実装:

<h:outputText id="text" value="woof" 
  rendered="#{animal.type == 'elephant' 
                  or animal.type == 'dog' and not(animal.mute)}"/>

またはオプション2:

カプセル化:

<h:outputText id="text" value="woof" rendered="#{animal.barkingAnimal}"/>

実装あり:

public class Animal {
     public boolean isBarkingAnimal() {
         return ("dog".equals(getType()) || "elephant".equals(getType())) && !isMute();
     }
...

どちらも機能します...しかし、シナリオを処理する正しい方法はどれですか?

10
TEL

個人的には、オプション#2を使用します。 ELを使用して問題を解決し、関数またはui:paramsを使用してxhtmlドキュメント全体で少し再利用することは非常に可能であることを知っていますが、Javaの移植性、保守性、およびテスト容易性に欠けているようですBeanの実装。

開発者がELとJavaの両方に堪能であり、xhtmlとJava Beanの両方を所有している場合、ELを使用するのはあまり意味がありません。サイズ> 1の条件付き評価を実行します。

Java側で実装するメリットが多すぎるようです:

  • IDE +コンパイラに頼る能力
  • 定数または列挙型(「dog」と「bark」の場合)を使用します。比較のためにコードの他の場所でも使用されている可能性があります...文字列値が変更された場合、発生したすべての出現箇所を手動で置き換える必要があります。コードベース
  • 適切なデータで問題のページに移動する代わりに、単体テストを使用してロジックを実行できます

オプション1を支持して私が聞いた(Stack以外の)主な引数の1つは次のとおりです。

「このロジックをビューに保持しておくと、コンポーネントがいつレンダリングされるかがはるかにわかりやすくなります。」

これは、アプリケーションの軽量化と複雑さの軽減の初期段階のアプリケーションに当てはまる可能性があることがわかりました。ただし、この方法を大規模に適用し、小規模なアプリケーションが成熟すると、条件付きのネズミの巣が発生し、維持するのが悪夢になる可能性があります。以下は、私が実際に目にしたものに似た例です。

<h:outputText value="grrr" 
    render="#{animal.type == 'dog' or animal.type == 'cat' or animal.type == 'horse' 
        or animal.type == 'pony' or animal.type == 'mule' or animal.type == 'lion'
        or animal.type == 'tiger' or (animal.type == 'bird' 
        and animal.subType == 'macaw') or .... continue this for another line or two}"
/>

または、私のお気に入り、互いに排他的なレンダリング条件を持つ複数のコンポーネントを使用して、表示できるさまざまな値を表す:

<h:outputText value="grr" render="#{theMonstrosityFromPreviousExample} />
<h:outputText value="cry" 
    render="#{animal.type == 'human' and animal.subType == 'baby'}" />
<h:outputText value="yo" 
    render="#{animal.type == 'human' and animal.subType == 'teenager'}" />
<h:outputText value="hello" 
    render="#{animal.type == 'human' and animal.subType == 'adult'}"/>

一度に最大4つのテキストを表示できますか?一見できませんが、各状態のチェックが必要になります。余談ですが、c:chooseに入れることもできるので、この例もデザインが悪いことに気付きましたが、これは以前に見たことがあります。

結局のところ、これは実際には何が表示されるかを決定するため、理論的にはまだ「表示」ロジックであり、xhtmlに含める必要がある概念的な引数があります。私が見つけた問題は、ビューテンプレートにこのようなロジックを含めると、レイアウトを長期的に理解することがはるかに困難になる可能性があり、問題を解決するこの方法が=を使用するよりも実際の利点を持っていることをまだ見ていませんJava Beanの実装。

1
TEL

ほとんどの場合、それは単に好みの問題です。あなたの懸念が単に状態を再利用することであるなら、あなたもそうすることができます:

_<ui:param name="animalCanBark" value="#{animal.type == 'elephant' 
              or animal.type == 'dog' and not(animal.mute)}" />
...
<h:outputText id="text" value="woof" rendered="#{animalCanBark}"/>
_

これは、記述する必要のある式が複数のオブジェクトを含む場合に便利です。たとえば、

_<ui:param name="showBarking" value="#{animal.type == 'elephant'
              and not facesContext.validationFailed" />
_

JavaコンパイラはJavaコードで型チェックを実行できるので、多くの人はELではなくJavaでこのタイプのロジックを記述することを好むと思います(また、ほとんどのIDEでは、Javaの方が.XHTMLファイルよりもオートコンプリートの方が優れていますが、これは一部の人にとって懸念事項です。

そうは言っても、いつか別の場所(別のFacelets/JSFページだけでなく)で使用される可能性があるモデルに関する情報である場合は、Javaコードで実行することをお勧めします。あなたが与えた例では、メソッドisBarkingAnimal()はモデルに関するいくつかの情報(Animal)を提供します。いつかは、(別のFaceletsページだけでなく)別のオブジェクトが知る必要があるときに役立つかもしれません与えられた動物が吠える場合。だから、私はおそらくそれで行きます。

5
elias

経験則として、.xhtmlファイルをできるだけロジックフリーにして、プレゼンテーションのみを処理するようにしてください。ですから、明らかにオプション2に進んでください。

3
SJuan76