java - tipos - para que sirve un modelo de negocio
¿Cuáles son las formas de mantener hashCode/es igual a la definición de negocio de la clase? (6)
¿Qué tal si escribes pruebas de unidad para cada clase que quieres proteger? Las pruebas unitarias deben
- Use la reflexión para contar el número de campos y compare con los nombres (y tipos) de campos almacenados localmente.
- Si se ha detectado un cambio en la cantidad de campos (o tipo de campos), invoque el código hash. Si el valor es el mismo, entonces falla el caso de prueba. Avise al desarrollador que los campos de una clase se han cambiado y que el desarrollador debe: Actualizar los iguales y Hashcose, y actualizar el test de unidad.
- Asegúrate de que la prueba de unidad se ejecute en una compilación nocturna.
Object javadocs y Josh Bloch nos dicen mucho sobre cómo se deben implementar hashCode / equals, y los buenos IDE manejarán campos de varios tipos correctamente. Un poco de discusión sobre todo lo que está here .
Esta pregunta es sobre el siguiente paso: ¿Cómo se asegura de que sigan siendo buenos?
En particular, creo que para la mayoría de las Clases, equals / hashCode debe implementarse como sugiere Bloch (y Eclipse y otros implementos de IDE), y tomar en cuenta todos los campos no derivados, de lógica empresarial, en esa clase. Al agregar nuevos campos a una clase como parte del trabajo continuo, las personas a menudo se olvidan de agregarlos a la implementación de equals / hashCode. Esto puede llevar a errores difíciles de encontrar, cuando dos objetos parecen iguales, pero de hecho difieren según el valor de un campo introducido recientemente.
¿Cómo puede un equipo (incluso de uno) ayudar a garantizar que el código equals / hash en una clase continúe teniendo en cuenta todos los campos relevantes, a medida que los campos miembros cambian?
Sé que los EqualsBuilder y HashCodeBuilder de Apache pueden usar la reflexión, lo que obviamente tomaría en cuenta los campos correctos, pero quiero evitar los costos de rendimiento de usarlos. ¿Existen otros enfoques para marcar los campos que no están incluidos en equals / hashCode, y deberían serlo? Análisis de código estático, características IDE, técnicas de prueba unitaria?
En esta pregunta parece ofrecerse una respuesta potencial.
No he investigado mucho el Proyecto Lombok , pero inmediatamente pensé que las anotaciones hmm funcionarían con un generador de código.
No es necesario que incluya todos los campos en su método de código hash. Si usó más de un campo en su algoritmo de código hash, entonces es probable que siga siendo bueno. Los algoritmos generados por IDE que he visto utilizan un valor constante primo aleatorio (en el momento de la implementación, no en la ejecución), así que asegúrese de que las clases puedan terminar juntas en el mismo mapa o árbol (por ejemplo, implementan el mismo interfaz) tienen diferentes valores constantes. A menos que, por supuesto, quieras igualdad en el nivel de la interfaz.
Nunca he visto que un algoritmo de código hash "salga mal"; te preocupa una cantidad desproporcionada de esto.
Nunca lo probé, pero ¿qué hay de http://code.google.com/p/equalsverifier/ ?
Parece que lo que está buscando es un complemento o característica en un IDE que realiza el análisis de las clases y genera advertencias si los métodos equals () y hashCode () no hacen referencia a todos los campos relevantes.
Básicamente, esto movería la sobrecarga de reflexión al IDE en lugar de permitir que tenga el costo durante el tiempo de ejecución.
Desafortunadamente, no conozco ningún complemento que haga esto, aunque ciertamente echaré un vistazo.
Por otro lado, ¿cómo podría una herramienta automatizada de este tipo saber qué campos son relevantes para la lógica empresarial? Probablemente deba marcar los campos irrelevantes con algo como una anotación, de lo contrario podría encontrarse con advertencias de las que no puede deshacerse, pero que sabe que son incorrectas.
Edición: esta respuesta no es útil, así que estoy compilando las sugerencias realmente útiles de mejores respuestas:
- Proyecto Lombok : el complemento de Eclipse que también funciona con herramientas de compilación para proporcionar la generación automática de
equals()
,hashCode()
y otro código de placa de caldera - ya que se genera en tiempo de compilación, cualquier cambio en la clase también actualizará automáticamente estos métodos - http://code.google.com/p/equalsverifier/ : proporciona una forma de realizar pruebas unitarias de manera automática
equals()
con reflexiones, no admitehashCode()
pruebashashCode()
Podría serializar sus objetos a una cadena usando una herramienta que encuentre sus propiedades usando la reflexión (XStream, por ejemplo) y almacenar esa cadena en un repositorio. Sus pruebas unitarias podrían volver a serializar sus objetos y comparar los resultados con sus valores almacenados.
Como parte de su propio proceso, haga que el almacenamiento de esas cadenas dependa de la validación manual de que su código de hash y sus iguales capturen correctamente todos los valores relevantes.