Un'espressione EL complessa deve essere sostituita da un solo getter javabean?

10

In JSF se ho un componente che esegue il rendering condizionalmente in base a un numero di variabili qual è il modo ottimale per gestire l'istruzione render ... dovrebbe la logica vivere nella dichiarazione del componente o in qualche forma di classe helper?

La trama del testo viene visualizzata solo quando un animale è un elefante o un cane e l'animale non è muto.

Opzione 1:

Implementazione nella vista:

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

o Opzione 2:

Encapsulation:

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

con implementazione:

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

Quindi funzionano entrambi ... ma qual è il modo giusto per gestire lo scenario?

    
posta TEL 04.01.2013 - 22:16
fonte

3 risposte

1

Personalmente, vorrei usare l'Opzione # 2. Mentre so che è molto possibile risolvere il problema usando EL e ottenere un po 'di riuso sui documenti xhtml usando le funzioni o ui: params sembra davvero che manchi della portabilità, manutenibilità e testabilità dell'implementazione del bean Java.

Se uno sviluppatore è fluente sia in EL che in Java e possiede sia i bean xhtml che Java, non sembra molto sensato usare EL per fare QUALSIASI valutazione condizionale con una dimensione > 1.

Sembra che ci siano troppi vantaggi nell'implementazione sul lato Java:

  • Capacità di appoggiarsi al compilatore IDE +
  • Usa costanti o enumerazioni (per "cane" e "abbaio"), è probabile che vengano usate altrove nel codice anche per i confronti ... se il valore della stringa cambia è molto divertente dover sostituire manualmente ogni occorrenza di attraverso una base di codice
  • Invece di dover navigare verso la pagina in questione con dati appropriati, posso esercitare la logica usando i test unitari

Uno degli argomenti principali che ho sentito (al di fuori dello Stack) a favore dell'opzione 1 è:

"È molto più facile vedere quando un componente esegue il rendering mantenendo questa logica nella vista."

Ho scoperto che questo potrebbe essere il caso di un'applicazione nella fase iniziale della sua vita in cui è più leggero e meno complicato. Tuttavia, applicando questa pratica su una scala più ampia e con un'applicazione più piccola, può causare un ratto di condizionali e diventare un incubo da mantenere. Ecco alcuni esempi simili a ciò che ho visto in natura:

<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}"
/>

O il mio preferito, utilizzando più componenti con condizioni di rendering esclusive l'una dell'altra per rappresentare i diversi valori che potrebbero essere visualizzati:

<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'}"/>

Possono essere visualizzati fino a 4 testi contemporaneamente? A prima vista non si può dire, sarà necessario un controllo di ogni condizione. Come nota a margine, mi rendo conto che questo esempio è anche di scarsa progettazione, in quanto potrebbero essere inseriti in una c: scegliere ... ma l'ho già visto prima.

Alla fine della giornata questa è ancora teoricamente la logica della "vista" poiché determina ciò che viene effettivamente visualizzato, quindi c'è un argomento concettuale che dovrebbe vivere nel xhtml. Il problema che ho riscontrato è che includere una logica come questa nel modello di visualizzazione può rendere il layout molto più difficile da comprendere a lungo termine e devo ancora vedere che questo metodo di risoluzione del problema offre vantaggi reali rispetto all'uso di Java implementazione del bean.

    
risposta data 05.01.2013 - 18:05
fonte
5

Nella maggior parte dei casi, è semplicemente una questione di gusti. Se la tua preoccupazione è semplicemente riutilizzare la condizione, puoi anche fare:

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

Questo è spesso utile quando l'espressione che devi scrivere coinvolge più di un solo oggetto, ad esempio:

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

Penso che molte persone preferiscano scrivere questo tipo di logica in Java anziché in EL perché il compilatore Java può eseguire il controllo del tipo nel codice Java (inoltre, la maggior parte degli IDE ha un migliore completamento automatico per Java quindi per i file .XHTML), che è una preoccupazione per alcuni.

Detto questo, se si tratta di un'informazione sul modello che un giorno potrebbe essere utilizzata in un altro posto (non solo su un'altra pagina Facelets / JSF), sarebbe una buona ragione per farlo nel codice Java. Nell'esempio che hai fornito, il metodo isBarkingAnimal() fornisce alcune informazioni sul modello ( Animal ), che un giorno potrebbe risultare utile quando un altro oggetto (non solo un'altra pagina di Facelets) ha bisogno di sapere se un dato animale abbaia. Quindi, probabilmente ci andrei.

    
risposta data 05.01.2013 - 01:52
fonte
3

Come regola generale, cerca di mantenere i file .xhtml il più possibile privi di logica, in modo che si occupino solo della presentazione. Quindi, chiaramente andare per l'opzione 2.

    
risposta data 04.01.2013 - 22:18
fonte

Leggi altre domande sui tag