solo - ¿Debería Java POJO tener validación de campo y lanzar excepciones en los métodos de establecimiento?
validar formulario primefaces (4)
Digamos que tenemos decenas de POJO java que representan mi dominio, es decir, mis datos en el sistema que fluyen como objetos entre diferentes capas de mi sistema. El sistema puede ser una aplicación web o una aplicación de escritorio simple. En qué consiste el dominio realmente no importa.
Al diseñar mi sistema, estoy confundido donde debería poner cualquier lógica de validación. Mis POJO (objetos de dominio) representan mis datos, y algunos de los campos dentro de esos objetos deben cumplir con ciertos criterios, pero si pongo mucha lógica de validación dentro de mis métodos de establecimiento, entonces la única manera de decirle al cliente que llama es para lanzar una excepción. Y si no quiero que el sistema falle, la excepción debe ser una excepción comprobada que debe ser detectada y manejada. La consecuencia de esto es que cada vez que creo un nuevo objeto utilizando métodos de establecimiento (o incluso constructores), tengo que volver a lanzar esa excepción o usar el bloque try-catch. No se siente bien ser forzado a usar try-catch en muchos métodos setter.
Entonces, la pregunta es dónde debo colocar mi lógica de validación, para no saturar mi código con una gran cantidad de bloques de repetición de prueba y de rebrote. Los mejores comedores de bytes de JAVA son bienvenidos a unirse a la discusión.
He investigado y buscado en Google, pero no he encontrado ninguna discusión específica sobre este tema, así que espero con gran entusiasmo para obtener una visión más profunda de cómo se deben hacer las cosas.
Además, no creo que haya una solución única para cada necesidad, y se reduce a su situación y preferencia.
Desde el punto de vista de la encapsulación, creo que la validación del configurador es el camino correcto, ya que es el lugar lógico para decidir si la información proporcionada es correcta y ofrecer una explicación detallada de lo que puede estar mal. Sin embargo, no estoy seguro de lo que quieres decir con:
Y si no quiero que el sistema se bloquee, la excepción debe ser una excepción comprobada ...
¿Por qué fallaría el sistema? Las excepciones no verificadas se pueden capturar muy bien como las marcadas. Debe averiguar cómo debe comportarse su programa cuando se produce un evento de este tipo, para que pueda decidir dónde capturarlos y qué hacer.
Checked vs unchecked ha sido, y sigue siendo, debatido de varias maneras y creencias, pero no veo ninguna razón por la que no debas lanzar una excepción no verificada. Simplemente haga una ConfigurationException
común (o use la IllegalArgumentException
ya IllegalArgumentException
) o lo que sea que flote en su barco, marque las firmas de sus métodos como corresponda y agregue los documentos java adecuados para que quienquiera que los llame sepa qué esperar, y tírelos cuando sea necesario.
Dependiendo de sus relaciones y jerarquía de objetos, otra solución podría ser algunos builders que ejecuten validaciones personalizadas justo al crear las instancias. Pero como dije, realmente depende del escenario, y es posible que no pueda evitar que otras personas realicen instancias de manera manual y llenen incorrectamente algunos objetos.
En algunas situaciones, la solución es hacer que todos los creadores sean privados y proporcionar un único punto de entrada para inicializar los objetos. Entonces toda la validación y el manejo de excepciones está en ese método de inicialización.
Esto también asegura que ningún objeto pueda inicializarse parcialmente.
El cambio del estado del objeto también puede manejarse de esta manera, haciendo que el objeto sea inmutable, excepto a través de un método de construcción / inicialización, esto puede convertirse en un desperdicio si se abusa de él.
Es posible que haya respondido a su propia pregunta cuando dijo
Algunos de los campos dentro de esos objetos deben cumplir con ciertos criterios
Siempre es útil pensar en las invariantes de su sistema, es decir, las cosas que desea mantener a toda costa o las reglas que siempre deben seguirse.
Sus POJO son la "última línea de defensa" para tales invariantes en sus objetos de datos y, por lo tanto, son un lugar adecuado, o incluso necesario, para colocar la lógica de validación. Sin dicha validación, un objeto ya no puede representar algo que tenga sentido en su dominio.
Estas invariantes del sistema forman un contrato entre sus objetos (o métodos) y sus "clientes". Si alguien está tratando de usarlos en contra del contrato (ojalá bien documentado), lanzar una excepción es lo correcto, ya que es responsabilidad del cliente usar las partes individuales del sistema correctamente.
Con el tiempo, comencé a favorecer las excepciones no controladas sobre las comprobadas para los casos de violaciones de contrato, en parte por la razón que mencionas, a saber, para evitar catch
bloques try
- catch
todas partes .
Las excepciones no verificadas estándar de Java incluyen:
- Excepción de puntero nulo
- Argumento de excepción ilegal
- IllegalStateException
- ExcepcionalOperaciónExcepción
Una guía de mejores prácticas es usar las excepciones marcadas cuando un error se considera recuperable y las excepciones no verificadas de lo contrario.
El capítulo 9 de " Effective Java, 2nd ed. " De Joshua Bloch proporciona más sabiduría sobre este tema:
- Ítem 57: usar excepciones solo para condiciones excepcionales
- Artículo 58: Utilice excepciones comprobadas para condiciones recuperables y excepciones de tiempo de ejecución para errores de programación
- Ítem 59: evitar el uso innecesario de las excepciones comprobadas
- Ítem 60: Favorecer el uso de excepciones estándar.
Ninguno de los anteriores debe disuadirlo de utilizar una lógica de validación adecuada en niveles superiores, especialmente para imponer reglas o restricciones comerciales específicas del contexto.
Si bien puede poner la lógica de validación en los métodos del establecedor de beans, descubrí que en la práctica, una separación más clara de las preocupaciones sería mover cualquier validación compleja a otra clase específica para la validación. Escúchame.
El uso de la validación de beans está bien, pero en muchos casos (para los que estoy seguro de que ahora se está encontrando), una simple anotación no llevará a cabo una validación suficiente. Los marcos como Spring tienen Validator
s que puedes implementar para hacer esto.
Existen numerosos beneficios para separar la lógica de validación:
- Código de reutilización. En algunos casos, la validación del configurador para un bean puede ser idéntica a la de otro bean. Esto también lleva adelante a pruebas unitarias más concisas.
- En muchos casos, no tratará con excepciones en absoluto, sino que mostrará un mensaje de error al usuario
- Puede iniciar sesión de manera adecuada sin llenar sus POJO con declaraciones de registro o forzándolas a implementar un registrador
- El código es mucho más legible y la intención se entiende mejor
Espero que ayude.