sistema - ¿Una buena biblioteca de diseño por contrato para Java?
proyecto biblioteca java (10)
Hace unos años, hice una encuesta de paquetes DbC para Java, y no estaba totalmente satisfecho con ninguno de ellos. Desafortunadamente no guardé buenas notas sobre mis hallazgos, y asumo que las cosas han cambiado. ¿Alguien se preocuparía por comparar y contrastar diferentes paquetes de DbC para Java?
Creo que muchas bibliotecas DbC fueron superadas por la palabra clave builtin assert , introducida desde Java 1.4:
- es un built-in, no se requiere otra biblioteca
- funciona con herencia
- puedes activar / desactivar en paquetes
- fácil de refactorizar (por ejemplo, no hay aserciones en los comentarios)
Existe una extensión Groovy que permite Design by Contract (tm) en código Groovy / Java - GContracts . Utiliza las llamadas anotaciones de cierre para especificar invariantes de clase, pre y postcondiciones. Los ejemplos se pueden encontrar en la wiki github del proyecto.
Mayor ventaja: es solo un único contenedor sin dependencias externas y se puede resolver a través de repositorios compatibles con Maven desde su ubicación en el repositorio central de Maven .
Google tiene una biblioteca de código abierto llamada contratos para Java .
Contracts for Java es nuestra nueva herramienta de código abierto. Las condiciones previas, las postcondiciones y las invariantes se agregan como expresiones booleanas de Java dentro de las anotaciones. De forma predeterminada, estos no hacen nada, pero se habilitan a través de un argumento JVM, se verifican en el tiempo de ejecución.
• @Requires, @Ensures, @ThrowEnsures and @Invariant specify contracts as Java boolean expressions • Contracts are inherited from both interfaces and classes and can be selectively enabled at runtime
Ha pasado mucho tiempo desde que los miré, pero encontré algunos enlaces antiguos. Uno fue para JASS .
El otro que yo había usado (y me gustó) fue iContract de Reliable Systems. Tenía una tarea ant que ejecutarías como preprocesador. Sin embargo, parece que no puedo encontrarlo con algunas búsquedas de Google, parece que se ha desvanecido. El sitio original ahora es una granja de enlaces. Consulte este enlace para conocer algunas formas posibles de llegar a él.
Hay una buena descripción general en WikiPedia sobre Design by Contract , al final hay una sección sobre idiomas con bibliotecas de soporte de terceros , que incluye una bonita serie de bibliotecas Java. La mayoría de estas bibliotecas de Java se basan en Java Assertions.
En el caso de que solo necesite la verificación previa, también hay una solución de validación de argumentos de método liviana, en SourceForge bajo Validación de argumentos de Java (implementación Java simple).
Dependiendo de su problema, tal vez el marco OVal , para la validación de Restricciones de campo / propiedad es una buena opción. Este marco le permite colocar las Restricciones en todo tipo de formas diferentes (Anotaciones, POJO, XML). Cree restricciones de clientes a través de POJO o lenguajes de scripting (JavaScript, Groovy, BeanShell, OGNL, MVEL). Y también parte implementa Programación por contrato .
Le recomiendo que considere el lenguaje de modelado de Java ( JML ).
Personalmente creo que las bibliotecas DbC disponibles en este momento dejan mucho que desear, ninguna de las bibliotecas que he visto funcionaba bien con la API Bean Validation.
Las bibliotecas que miré han sido documentadas here
La API de Validación de Bean tiene muchas más opciones con los conceptos de DbC. En ciertos casos, Bean Validation API no se puede usar como un POJO simple (código administrado no CDI). IMO una envoltura de pensamiento alrededor de la API de Validación de Bean debería ser suficiente.
Descubrí que las bibliotecas existentes son un poco difíciles de agregar a los proyectos web existentes dado que se implementan a través de AOP o instrumentación de código Byte. Probablemente con el advenimiento de Bean Validation API, este tipo de complejidad para implementar DbC no se justifica.
También he documentado mi despotricamiento en esta post y espero construir una pequeña biblioteca que aproveche la API de Validación de Bean.
Probé contract4J una vez y lo encontré utilizable pero no perfecto. Está creando contratos para y después de llamadas a métodos e invasores en toda la clase.
El contrato se crea como una afirmación del método. El problema es que el contrato en sí está escrito en una cadena por lo que no tiene soporte IDE para los contratos ni compila el tiempo de compilación si el contrato aún funciona.
Un enlace a la library
Si desea un soporte básico simple y simple para expresar sus contratos, eche un vistazo a valid4j (que se encuentra en Maven Central como org.valid4j: valid4j). Te permite expresar tus contratos usando hamcrest-matchers regulares en código simple (sin anotaciones, ni comentarios).
Para precondiciones y postcondiciones (básicamente aserciones -> lanzando AssertionError):
import static org.valid4j.Assertive.*;
require(inputList, hasSize(greaterThan(0)));
...
ensure(result, lessThan(4.0));
Si no está satisfecho con la política global predeterminada (lanzando AssertionError), valid4j proporciona un mecanismo de personalización que le permite proporcionar su propia implementación de org.valid4j.AssertiveProvider.
Campo de golf:
Sugeriría una combinación de algunas herramientas:
La
assert condition...
Verify.verify(condition...)
Javaassert condition...
o es un primo Groovy más avanzado,Preconditions.checkXXXX(condition...)
de GuavaPreconditions.checkXXXX(condition...)
yVerify.verify(condition...)
, o una biblioteca como AssertJ , si todo lo que necesita es solo hacer comprobaciones simples en su código ''principal'' o ''prueba''obtendrás más funciones con una herramienta como OVal ; puede verificar tanto los objetos como los argumentos del método y los resultados, también puede activar las comprobaciones manualmente (por ejemplo, para mostrar errores de validación en la interfaz de usuario antes de llamar a un método). Puede comprender anotaciones existentes, por ejemplo, de JPA o
javax.validation
(como@NotNull
,@Pattern
,@Column
), o puede escribir restricciones en línea como@Pre(expr="x >= 0 && x <= y")
. Si la anotación está@Documented
, las verificaciones también serán visibles en Javadocs (no es necesario que también las describa allí).OVal usa la reflexión, que puede generar problemas de rendimiento y otros problemas en algunos entornos, como Android; entonces debería considerar una herramienta como Google Cofoja , que tiene menos funcionalidad, pero depende de la Herramienta de procesamiento de anotaciones en tiempo de compilación en lugar de la reflexión