EqualsBuilder & HashCodeBuilder, mejorando lo visto

Siguiendo lo comentado en la entrada anterior, cuando nuestras clases empiezan a acumular un buen número de propiedades, generar de forma automática el método ‘equals()’ engendra un monstruo.

Si bien podemos refactorizar e intentar maquillar el asunto, lo más probable es que caigamos en lo que se conoce como un antipatrón, y más concretamente acabaremos reinventando la rueda cuadrada. ¿Qué significa esto? Pues que gastaremos tiempo en hacer algo que ya se ha hecho con anterioridad y seguramente nuestra solución sea ‘peor’ que la que ya existe.

Esta situación ocurre a diario, cuando estamos aprendiendo nos viene bien para ejercitar un poco el coco pero cuando tenemos plazos de entrega, hay que ser práctico. En muchas ocasiones me sorprendo a mi mismo uniendo piezas ajenas para llevar a cabo pequeñas funcionalidades, esto no es malo mientras entiendas lo que estas haciendo, de lo contrario la cosa puede degenerar en una variante de la programación basada en el copiar/pegar (Otro antipatrón).

Pero no nos desviemos del tema, necesitamos encontrar una solución para nuestro problema con los ‘equals()’. Las preguntas clave que hay que hacerse son:

  1. ¿Soy el primero en enfrentarme a este problema? (Probablemente no)
  2. ¿Habrá alguna solución ya existente para este problema? (Probablemente sí)

Es aquí donde entra en juego la fundación Apache y sus archiconocidas librerías Apache Commons, sin entrar en grandes detalles, estas librerías te harán la vida más fácil como programador java, poco a poco iremos examinándolas con más detalle.

Imagen

Concretamente para este caso, las clases EqualsBuilder y HashCodeBuilder de la librería Apache Commons Lang cubren nuestras necesidades. Vamos a verlas en acción, comencemos por el método ‘equals()’ de la clase ‘Persona’ utilizada en la entrada anterior:


	@Override
	public boolean equals(Object obj) {

		if (this == obj) {
			return true;
		}

		if (obj == null) {
			return false;
		}

		if (!(obj instanceof Persona)) {
			return false;
		}

		Persona other = (Persona) obj;

		EqualsBuilder eBuilder = new EqualsBuilder();

		eBuilder = eBuilder.append(this.dni, other.dni);
		eBuilder = eBuilder.append(this.edad, other.edad);
		eBuilder = eBuilder.append(this.nombre, other.nombre);

		return eBuilder.isEquals();
	}

La mejora en cuanto a legibilidad y mantenibilidad es muy notable, veamos si sucede igual con el método ‘hashCode()’:


	@Override
	public int hashCode() {

		// Creamos una instancia, el primer valor es para la
		// inicialización, el segundo el número primo para las
		// multiplicaciones
		HashCodeBuilder hcBuilder = new HashCodeBuilder(17, 31);

		hcBuilder.append(this.dni);
		hcBuilder.append(this.edad);
		hcBuilder.append(this.nombre);

		return hcBuilder.toHashCode();
	}

La respuesta es afirmativa, el código se simplifica a costa de añadir una libería (‘jar’) a nuestro proyecto. Además podemos estar tranquilos en lo que se refiere a su implementación, el método ‘hashCode()’ esta hecho siguiendo las directrices de Effective Java (Igual este libro es interesante :)).

No he comentado nada en relación a como añadir la librería, todo depende de como gestionemos las dependencias en nuestro proyecto, para este ejemplo no me he complicado en exceso y he añadido el ‘jar’ de la librería (‘commons-lang3-3.1.jar’) al Classpath del proyecto, con Maven añadiríamos la dependencia en el POM de nuestro proyecto (Un tema interesante para una futura entrada).

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s