Estructura de bean de respaldo JSF (mejores prácticas)

118

Espero que en esta publicación pueda obtener las opiniones de la gente sobre las mejores prácticas para la interfaz entre las páginas JSF y los beans de respaldo.

Una cosa con la que nunca puedo conformarme es la estructura de mis granos de respaldo. Además, nunca he encontrado un buen artículo sobre el tema.

¿Qué propiedades pertenecen a qué frijoles de respaldo? ¿Cuándo es apropiado agregar más propiedades a un bean dado en lugar de crear un nuevo bean y agregarle las propiedades? Para aplicaciones simples, ¿tiene sentido tener un solo bean de respaldo para toda la página, considerando la complejidad que implica inyectar un bean en otro? ¿Debería el bean de respaldo contener alguna lógica empresarial real o debería contener estrictamente datos?

No dude en responder estas preguntas y otras que puedan surgir.


En cuanto a reducir el acoplamiento entre la página JSF y el bean de respaldo, nunca permito que la página JSF acceda a las propiedades de ninguna propiedad del bean de respaldo. Por ejemplo, nunca permito algo como:

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

Siempre requiero algo como:

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

con un valor de frijol de respaldo de:

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

Cuando recorro una colección, uso una clase contenedora para evitar profundizar en un objeto en una tabla de datos, por ejemplo.

En general, este enfoque me parece "correcto". Evita cualquier acoplamiento entre la vista y los datos. Por favor corrígeme si estoy equivocado.

Zack Marrapese
fuente
¿Puede darnos un ejemplo para: cuando recorro una colección, uso una clase contenedora para evitar profundizar en un objeto en una tabla de datos, por ejemplo?
Koray Tugay
2
Para obtener más información, consulte la respuesta de BalusC en stackoverflow.com/questions/7223055/…
Zack Marrapese

Respuestas:

146

Es posible que desee verificar esto: hacer distinciones entre diferentes tipos de beans administrados por JSF .

Aquí hay una descripción de los diferentes tipos de frijoles, tal como los define Neil Griffin en el artículo anterior:

  • Model Managed-Bean : normalmente ámbito de sesión. Este tipo de bean administrado participa en la preocupación del "Modelo" del patrón de diseño MVC. Cuando vea la palabra "modelo", piense en DATOS. Un modelo-bean JSF debe ser un POJO que siga el patrón de diseño JavaBean con propiedades de encapsulación de captadores / definidores. El caso de uso más común de un bean modelo es ser una entidad de base de datos o simplemente representar un conjunto de filas del conjunto de resultados de una consulta de base de datos.
  • Backing Managed-Bean : normalmente alcance de solicitud. Este tipo de bean administrado participa en la preocupación de "Ver" del patrón de diseño MVC. El propósito de un bean de respaldo es admitir la lógica de la interfaz de usuario y tiene una relación 1 :: 1 con una vista JSF o un formulario JSF en una composición Facelet. Aunque normalmente tiene propiedades de estilo JavaBean con captadores / definidores asociados, estas son propiedades de la Vista, no del modelo de datos de la aplicación subyacente. Los backing-beans JSF también pueden tener métodos JSF actionListener y valueChangeListener.
  • Controller Managed-Bean : Normalmente solicita el alcance. Este tipo de bean administrado participa en la preocupación del "controlador" del patrón de diseño MVC. El propósito de un bean controlador es ejecutar algún tipo de lógica empresarial y devolver un resultado de navegación al controlador de navegación JSF. Los beans de controlador JSF suelen tener métodos de acción JSF (y no métodos actionListener).
  • Soporte Managed-Bean : normalmente, ámbito de sesión o aplicación. Este tipo de bean "admite" una o más vistas en la preocupación "Vista" del patrón de diseño MVC. El caso de uso típico es proporcionar una ArrayList a JSF h: listas desplegables selectOneMenu que aparecen en más de una vista JSF. Si los datos de las listas desplegables son específicos del usuario, el bean se mantendrá en el alcance de la sesión. Sin embargo, si los datos se aplican a todos los usuarios (como una lista desplegable de provincias), entonces el bean se mantendrá en el ámbito de la aplicación, de modo que pueda almacenarse en caché para todos los usuarios.
  • Utilidad Managed-Bean : normalmente ámbito de aplicación. Este tipo de bean proporciona algún tipo de función de "utilidad" a una o más vistas JSF. Un buen ejemplo de esto podría ser un bean FileUpload que se puede reutilizar en múltiples aplicaciones web.
cecemel
fuente
8
Este es un gran articulo. Nunca lo había visto antes y definitivamente me alegro de que lo haya publicado. Quien votó en contra está loco. No es específico de iceFaces.
Zack Marrapese
2
El enlace al artículo real parece haber desaparecido.
Bill Rosmus
Puede encontrar una copia aquí
ChrLipp
10
Aún así, no puedo llegar a la conclusión de que esta respuesta está actualmente en 71 votos a favor. Quien haya implementado su aplicación JSF de acuerdo con esas reglas debe, sin duda, despotricar después de que JSF es un marco terriblemente opaco y que sus aplicaciones JSF son un gran lío de código y todos culpan a JSF en lugar de su propio enfoque incorrecto basado en las lecciones incorrectas y las llamadas "mejores prácticas" aprendidas.
BalusC
¿Alguna de las lógicas de estos beans se ejecuta en el navegador en lugar de en el servidor?
eskalera
14

Gran pregunta. Sufrí mucho con el mismo dilema cuando me mudé a JSF. Realmente depende de tu aplicación. Soy del mundo Java EE, por lo que recomendaría tener la menor lógica comercial posible en sus beans de respaldo. Si la lógica está puramente relacionada con la presentación de su página, entonces está bien tenerla en el bean de respaldo.

Creo que una de las (muchas) fortalezas de JSF es en realidad el hecho de que puede exponer objetos de dominio directamente en los beans administrados. Por lo tanto, recomendaría encarecidamente el <:outputText value="#{myBean.anObject.anObjectProperty}" />enfoque, de lo contrario, terminará haciendo demasiado trabajo al exponer manualmente cada propiedad. Además, sería un poco complicado insertar o actualizar datos si encapsulara todas las propiedades. Hay situaciones en las que un solo objeto de dominio puede no ser suficiente. En esos casos, preparo un ValueObject antes de exponerlo en el bean.

EDITAR: En realidad, si va a encapsular todas las propiedades del objeto que desea exponer, le recomendaría que en su lugar vincule los componentes de la interfaz de usuario al bean de respaldo y luego inyecte el contenido directamente en el valor del componente.

En términos de estructura de bean, el punto de inflexión para mí fue cuando ignoré a la fuerza todo lo que sabía sobre la creación de aplicaciones web y comencé a tratarlo como una aplicación GUI. JSF imita mucho a Swing y, por lo tanto, las mejores prácticas para desarrollar aplicaciones Swing también se aplicarían principalmente a la creación de aplicaciones JSF.

Allan Lykke Christensen
fuente
Gracias por tu conocimiento. Realmente nunca hice mucho en cuanto a aplicaciones de swing (aparte de proyectos académicos hace mucho tiempo). ¿Cuáles son algunos buenos principios de las aplicaciones de swing? Además, ¿por qué es un lío al insertar y actualizar valores? me parece lo mismo?
Zack Marrapese
5

Creo que lo más importante con sus frijoles de respaldo es separar sus lógicas. Si tiene una página principal para un sistema CMS, vería como una mala práctica poner cada fragmento de código en un bean porque:

  1. El frijol se volvería muy grande eventualmente
  2. Es más fácil para otras personas encontrar lo que buscan si están solucionando problemas en la página de inicio de sesión, si luego pueden buscar fácilmente el archivo loginBean.java.
  3. A veces tiene pequeñas piezas de funcionalidad que son claramente distintas del resto de su código, al separar esto, me imagino que le resultaría más fácil volver a desarrollar / expandir este código en algo más grande, cuando ya tiene un buen bean con buena estructura.
  4. Tener 1 gran bean, para hacerlo todo, lo hará más dependiente de la memoria si / cuando tiene que hacer declaraciones como esta MyBigBean bigBean = new MyBigBean (); en lugar de usar la funksjonality que realmente necesitaba haciendo LoginBean loginBean = new LoginBean (); (Corrígeme si me equivoco aquí ???)
  5. En mi opinión, separar tus frijoles es como separar tus métodos. No desea un método grande que se ejecute en cientos de líneas, sino dividirlo con nuevos métodos que manejen su tarea específica.
  6. Recuerde, lo más probable es que alguien que no sea usted también tenga que trabajar en sus proyectos JSF.


En cuanto al acoplamiento, no lo veo como un problema problemático permitir que sus páginas JSF accedan también a las propiedades de los objetos en su backingbean. Este es un soporte que está integrado en JSF, y realmente hace que sea más fácil de leer y construir imo. Ya está separando estrictamente la lógica MVC. Al hacer esto, te ahorras toneladas de líneas con getters y setters en tu backingbean. Por ejemplo, tengo un objeto realmente enorme que me dieron los servicios web, donde necesito usar algunas propiedades en mi presentación. Si tuviera que hacer un getter / setter para cada propiedad, mi bean se expandiría con al menos 100 líneas más de variables y métodos para obtener las propiedades. Al utilizar la funcionalidad JSF incorporada, se ahorra tiempo y valiosas líneas de código.

Solo mis 2 centavos con respecto a esto, incluso con la pregunta ya marcada como respondida.

Chris Dale
fuente
1
sin embargo, si tiene un objeto enorme que está en su bean, y tiene, digamos, 15 funciones EL excavando en ese objeto desde la página JSF, ahora está atado no solo al bean, sino a ese objeto. Por lo tanto, será difícil eliminar ese objeto sin romper la interfaz de usuario.
Zack Marrapese
1
¿Pero su frijol de respaldo no estará atado a ese objeto también? ¿Y tu interfaz de usuario vinculada al bean de respaldo? Cuando tenga que modificarlo, tendrá que cambiar todos sus getters / setters tanto en la interfaz de usuario como en el bean.
Chris Dale
4

Puede que no responda a todas sus preguntas, porque pocas parecen depender de un caso a otro.

  • Está bien tener una lógica empresarial en su bean de respaldo. Depende de dónde vengas. Si está practicando el diseño impulsado por dominios, tendrá la tentación de incluir la lógica empresarial en el bean de respaldo o también puede ser lógica de persistencia. Ellos argumentan que por qué objetar tan tonto. El objeto no solo debe contener estado, sino también comportamiento. Por otro lado, si considera la forma tradicional de hacer las cosas de Java EE, es posible que tenga ganas de tener datos en su bean de respaldo, que también puede ser su bean de entidad, y otra lógica empresarial y de persistencia en algún bean de sesión o algo así. Eso también está bien.

  • Está perfectamente bien tener un solo bean de respaldo para toda la página. No veo ningún problema con esto solo. Puede que esto no parezca correcto, pero depende del caso.

  • Su otra pregunta depende mucho más del caso que tenga entre manos. Preferiría ir controlado por dominio aquí, podría ser apropiado agregar propiedades al existente o crear un nuevo bean para eso. Cual siempre se adapta mejor. No creo que haya una fórmula mágica para esto.

  • Qué propiedades pertenecen a qué bean de respaldo. Bueno, ¿no depende del objeto de dominio? O puede ser que la pregunta no sea tan clara.

Además, en su ejemplo de código dado, no veo ningún beneficio enorme.

Adeel Ansari
fuente
si, por ejemplo, tuviéramos que cambiar de usar POJO elaborados en casa creados con consultas JDBC, a entidades Hibernate que tienen nombres de campo ligeramente diferentes, no solo tendríamos que cambiar el bean de respaldo. También tendríamos que cambiar la página JSF. No es así con mi ejemplo de código. Simplemente cambie el frijol.
Zack Marrapese
En ese caso, puede crear sus beans de respaldo, entidades. entonces solo necesitas cambiar las páginas JSF. ¿O depende de por qué cambiaría el nombre de las propiedades de todos modos? eso solo tendría sentido cuando cambia el nombre del campo para que coincida con el nombre de la columna de su base de datos. Pero ese es un caso completamente diferente.
Adeel Ansari
4

No es necesario que mantenga solo un bean de respaldo por página. Depende de la funcionalidad, pero la mayoría de las veces tenía un bean por página, ya que en su mayoría una página maneja una funcionalidad. Por ejemplo, en una página tengo un enlace de registro (vincularé con RegisterBean) y un enlace de cesta de la compra (ShoopingBasketBean).

Yo uso este <: outputText value = "# {myBean.anObject.anObjectProperty}" /> ya que normalmente sigo respaldando beans como beans de acción que contienen objetos de datos. No quiero escribir un contenedor en mi bean de respaldo para acceder a las propiedades de mis objetos de datos.

Bhushan Bhangale
fuente
0

Me gusta probar el código comercial sin View, por lo que considero BackingBeans como interfaces desde el código de View a Model. Nunca coloco ninguna regla o proceso en un BackingBean. Ese código entra en Servicios o Ayudantes, lo que permite su reutilización.

Si usa validadores, elimínelos de su BackingBean y haga referencia a ellos desde su método de validación.

Si accede a los DAO para completar selecciones, radios, casillas de verificación, hágalo siempre desde un BackingBean.

¡Créame!. Puede inyectar un JavaBean en un BackingBean, pero intente inyectar un BackingBean en otro. Pronto estará en una nigntmare de mantenimiento y comprensión del código.

jjruiz
fuente