¿Debería una expresión EL compleja ser reemplazada por un solo captador javabean?


10

En JSF si tengo un componente que renderiza condicionalmente en función de una serie de variables, ¿cuál es la forma óptima de manejar la declaración de renderización ... ¿debería la lógica vivir en la declaración del componente o en alguna forma de clase auxiliar?

El texto woof solo se muestra cuando un animal es un elefante o un perro y el animal no está mudo.

Opción 1:

Implementación en la vista:

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

u Opción 2:

Encapsulación:

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

con implementación:

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

Entonces ambos funcionan ... pero ¿cuál es la forma correcta de manejar el escenario?


Para ese ejemplo particular, usaría el. Parece solo ver datos relacionados. Si tiene algo de lógica en su código java barking animalsporque llamaría a ese método, ya que ya existe. Si se trata de una lógica de vista que utiliza en varios sitios, puede crear una función el a partir de ella.

El lenguaje de expresión se llamaba originalmente el más simple expresión posible lengua de manera que puede hacer alusión a su uso previsto. Mi propio punto de vista: si es una lógica de vista, EL puede ser apropiado; si es lógica de negocios, no lo es.
McDowell el

Respuestas:


5

En la mayoría de los casos, es simplemente una cuestión de gustos. Si su preocupación es simplemente reutilizar la afección, también podría hacer lo siguiente:

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

Esto suele ser útil cuando la expresión que necesita escribir involucra más de un solo objeto, por ejemplo:

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

Creo que muchas personas prefieren escribir este tipo de lógica en Java en lugar de en EL porque el compilador de Java puede verificar el tipo en el código Java (también, la mayoría de los IDE tienen una mejor autocompletación para Java que para los archivos .XHTML), lo cual es una preocupación para algunos.

Dicho esto, si se trata de información sobre el modelo que algún día se puede usar en otro lugar (no solo en otra página Facelets / JSF), sería una buena razón para hacerlo en su código Java. En el ejemplo que proporcionó, el método isBarkingAnimal()proporciona información sobre el modelo ( Animal), que algún día podría ser útil cuando otro objeto (no solo otra página de Facelets) necesita saber si un animal dado ladra. Entonces, probablemente iría con eso.


3

Como regla general, trate de mantener los archivos .xhtml lo más libres de lógica posible, para que solo se ocupen de la presentación. Entonces, ve claramente por la opción 2.


2
¿Es la lógica que el modelo necesita preocuparse? Si se usa más de una vez, ¿por qué usar un alias usando <c:set>o <ui:param>no sería una opción?

Ese ejemplo no tiene lógica de modelo detrás de él. Cambiaría la lógica de vista a la lógica de modelo, que genera código java que ni siquiera se llama dentro de java. Si la clase se Animalencuentra en otro entorno (remoto) o la mano de los programadores es irrelevante para ella.

1

Personalmente, usaría la Opción # 2. Si bien sé que es muy posible resolver el problema usando EL y obtener un poco de reutilización en los documentos xhtml usando funciones o ui: params, parece que realmente carece de la portabilidad, mantenibilidad y capacidad de prueba de la implementación del bean Java.

Si un desarrollador tiene fluidez tanto en EL como en Java y posee los beans xhtml y Java, no parece tener mucho sentido usar EL para hacer CUALQUIER evaluación condicional con un tamaño> 1.

Parece que hay demasiados beneficios para implementar en el lado de Java:

  • Capacidad para apoyarse en el compilador IDE +
  • Use constantes o enumeraciones (para "perro" y "ladrido"), lo más probable es que también se usen en otras partes del código para realizar comparaciones ... si el valor de la cadena cambia, es realmente divertido tener que reemplazar manualmente cada aparición en un base de código
  • En lugar de tener que navegar a la página en cuestión con los datos apropiados, puedo ejercitar la lógica usando pruebas unitarias

Uno de los principales argumentos que he escuchado (fuera de Stack) a favor de la Opción 1 es:

"Es mucho más fácil ver cuándo se procesa un componente si mantiene esta lógica en la vista".

Descubrí que este podría ser el caso de una aplicación en la etapa inicial de su vida, donde es más liviana y menos complicada. Sin embargo, la aplicación de esta práctica a mayor escala y a medida que una aplicación más pequeña madura puede causar un nido de ratas condicionales y convertirse en una pesadilla para mantener. Aquí hay un par de ejemplos similares a los que he visto en la naturaleza:

<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 mi favorito, usar múltiples componentes con condiciones de representación que son exclusivos entre sí para representar los diferentes valores que se pueden mostrar:

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

¿Se pueden mostrar hasta 4 textos a la vez? A primera vista no se puede ver, será necesario verificar cada condición. Como nota al margen, me doy cuenta de que este ejemplo también tiene un diseño deficiente, ya que estos podrían ponerse en ac: elegir ... pero ya he visto esto antes.

Al final del día, esto sigue siendo teóricamente una lógica de "vista", ya que determina lo que realmente se muestra, por lo que hay un argumento conceptual que debería vivir en el xhtml. El problema que he encontrado es que incluir una lógica como esta en la plantilla de vista puede hacer que el diseño sea mucho más difícil de entender a largo plazo y todavía tengo que ver que este método para resolver el problema tiene un beneficio real sobre el uso de Java implementación de frijol.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.