Un objeto es inmutable si su estado no puede cambiar luego de su construcción. Los objetos inmutables no exponen forma alguna de que otros objetos cambien su estado; los atributos del objeto son inicializados una sólo una vez dentro del constructor y nunca cambian.

En este artículo, definiremos los pasos para crear una clase inmutable en Java y revisaremos los errores de los programadores al crear una clase inmutable.

1. Usos de una clase inmutable

Hoy en día, la especificación “debe-tener” para toda aplicación de software es que se pueda distribuir y que se multi proceso. Las aplicaciones multi-proceso son un dolor de cabeza para los desarrolladores considerando que los desarrolladores requieren proteger el estado de los objetos  de las modificaciones por parte de otros procesos concurrentes que requieren modificar el mismo objeto, para este propósito, los desarrolladores normalmente utilizan los bloques de Sincronización en aquellos lugares donde se modifica el estado del proceso.

Con las clases inmutables, los estados nunca se modifican; cada modificación del estado de los objetos resulta en una nueva instancia, por lo tanto cada hilo utiliza una instancia diferente y los desarrolladores no deben preocuparse sobre las modificaciones por procesos concurrentes.

2. Clases inmutables populares en Java

String es la clase inmutable más popular en Java. Cuando se inicializa el valor no puede ser modificado. Operaciones como trim(), substring(), replace() siempre devuelven una nueva instancia y no afecta la instancia actual, es por eso que siempre utilizamos trim() de la siguiente forma:

Otro ejemplo del JDK son las clases de envoltura tales como: Integer, Float, Boolean … estas clases no modifican el estado, sin embargo crean una nueva instancia cada que se requiere modificar estas clases:

Después de llamar a+=3, se crea una nueva instancia para guardar el valor 6 y la primera instancia se pierde.

3. Como se crea una clase Inmutable

A fin de crear una clase inmutable, debes seguir los siguientes pasos:

  1. Se debe hacer que la clase sea final, así ninguna otra clase puede heredar de ella.
  2. Se debe hacer a todos los atributos final, así estos serán inicializados una vez dentro del constructor y no se podrán modificar luego.
  3. No exponer los métodos de asignación (métodos set)
  4. Cuando exponga métodos que modifican el estado de la clase, siempre debe devolver una nueva instancia de la clase.
  5. Si la clase tiene objetos que son mutables:
    • Dentro del constructor, debes estar seguro de utilizar una copia clonada de los argumentos y nunca configure su campo mutable a la instancia real pasada a través del constructor, esto es para evitar que los clientes que pasen el objeto lo modifiquen posteriormente.
    • Debe estar seguro de siempre devolver una copia clonada del atributo y nunca devolver la instancia del objeto real.

3.1 Clases Inmutables Simples

Sigamos los siguientes pasos y creemos nuestra clase inmutable (ImmutableStudent.java).

La clase presentada es una clase inmutable simple que no tiene ningún objeto mutable y nunca expone los atributos de ninguna manera; esta clase se utiliza generalmente con propósitos de almacenamiento en caché.

3.2 Paso de Objetos Mutables a Clases Inmutables

Ahora, compliquemos un poco nuestro ejemplo, crearemos una clase mutable denominada Age y agregaremos esta como un atributo de ImmutableStudent:

Agregamos este atributo a la clase inmutable:

Entonces agregamos un atributo mutable del tipo Age a nuestra clase inmutable y agregamos esta en el constructor.

Creemos un ejemplo sencillo en donde verificaremos que nuestra clase inmutables ImmutableStudent no es más inmutable:

Luego de ejecutar la prueba, tenemos la siguiente salida:

A fin de corregir esto y hacer que nuestra clase sea inmutable nuevamente, seguimos la recomendación #5 de los pasos que mencionamos para la creación de objetos inmutables. Entonces modificamos el constructor a fin de clonar el argumento que pasamos de la clase Age y utilizamos la instancia de este objeto.

Ahora, si ejecutamos nuestra prueba, tenemos la siguiente salida:

Tal como puede observar, la edad de Alex nunca se ve afectada luego de la construcción y nuestra clase volvió a ser inmutable.

3.3. Devolviendo Objetos Mutables de Clases Inmutables

Sin embargo, nuestra clase aún no es completamente inmutable, propongamos el siguiente escenario:

Salida:

De nuevo, de acuerdo al paso #4, cuando se devuelve atributos mutables desde objetos inmutables, debes devolver una instancia clone de esta y no una instancia real del atributo.

Entonces modificamos getAge() a fin de devolver el clone del objeto:

Ahora la clase es completamente inmutable y no proporciona una forma o método para que otros objetos modifiquen el estado:

4. Conclusión

Las clases inmutables proporcionan muchas ventajas especialmente cuando se utilizan en forma correcta en procesos concurrentes. La única desventaja es que consume más memoria que las clases tradicionales desde que cada modificación implica una nueva instancia de la clase, pero, un desarrollador no debe desestimar el sobre consumo de memoria ya que es insignificante comparado con las ventajas de este tipo de clases.

Finalmente, un objeto es inmutable si este puede presentar solo un estado a los otros objetos, no importando donde y cuando se llama a los métodos. De ser así, es seguro para subprocesos con cualquier definición de seguridad de subprocesos.


Este artículo se encuentra en base a How to Create an Immutable Class in Java,

Como se crea una clase inmutable en Java
Si te gusto, comparte ...Email this to someone
email
Share on Facebook
Facebook
Tweet about this on Twitter
Twitter
Share on LinkedIn
Linkedin
Share on Google+
Google+
Etiquetado en:        

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Facebook
A %d blogueros les gusta esto: