Invariantes de clase
# Invariantes de clase

Un objeto invariante, o una representación invariante, es un constructo de programación que consiste en una colección de propiedades invariantes que se mantienen intactas sea cual sea el estado del objeto. Esto garantiza que el objeto cumplirá siempre con ciertas condiciones predefinidas, y que los métodos pueden, en consecuencia, hacer referencia al objeto sin el riesgo de hacer presunciones imprecisas.

En programación, concretamente en programación orientada a objetos, las «invariantes de clase» son invariantes usadas para restringir los objetos de una clase. Los métodos de la clase deben respetar la invariante. La invariante de la clase restringe el estado guardado en el objeto.

Las invariantes de la clase se establecen durante su construcción y se mantienen entre las llamadas a métodos públicos. Es posible romper la invariabilidad de la clase entre llamadas a métodos privados, pero no es aconsejable.

Definir invariantes de clase puede ayudar a los programadores y controladores de calidad a localizar más errores de software durante las pruebas de software.

## Clases invariantes y herencia

Las ventajas de las invariantes de son más evidentes en presencia de herencia, ya que las invariantes de clase se heredan, es decir, «las invariantes de todas las clases superiores se aplican a la clase actual»

La herencia permite que las clases derivadas alteren la implementación de sus clases base, por lo que una clase derivada podría cambiar el estado de sus instancias de manera incorrecta desde el punto de vista de su clase base. La preocupación por este comportamiento no deseado lleva a algunos diseñadores de software a favorecer la composición sobre la herencia (por ejemplo, «La herencia rompe la encapsulación»).

Sin embargo, debido a la herencia, las invariantes de una clase cualquiera consisten en la suma de todas sus aserciones invariantes con las invariantes heredadas de su clase base. Esto significa que aunque las clases derivadas pueden acceder a los datos de implementación de su clase base, las invariantes de la clase base evitan que las derivadas manipulen estos datos de manera que produzcan una instancia incorrecta en tiempo de ejecución.

## Herramientas de programación de soporte a invariantes

### Aserciones

Algunos de los lenguajes de programación más comunes, como C++ y Java permiten el uso de aserciones por defecto, estas pueden usarse para definir invariantes de clase.

Un patrón de diseño común para implementar las invariantes de clase en el constructor del objeto es lanzar una excepción si la invariante no se cumple. Dado que los métodos respetan las invariantes, pueden asumir su validez y no necesitan verificarlas explícitamente.

### Soporte nativo

Las invariantes de clase son un componente esencial para el patrón de diseño por contrato. Por ello, los lenguajes que proporcionan un soporte completo al diseño por contrato, como Ada, Eiffel o D (lenguaje de programación), también proporcionan un soporte completo a las invariantes de clase.

### Soporte no nativo

Java dispone de una herramienta más potente llamada Java Modeling Language que ofrece un método más robusto para definir invariantes de clase.

## Ejemplos

### Soporte nativo

**D**

El lenguaje de programación D dispone de soporte nativo a las invariantes de clase, además de otras técnicas de diseño por contrato.

**Eiffel**

En Eiffel, las invariantes de clase se detalla al final de la clase precedidas por la palabra clave invariant.

### Soporte no nativo

**Java**

Este es un ejemplo de invariantes de clase en Java con Java Modeling Language. Las invariantes deben cumplirse después de que finalice el constructor del objeto y al entrar y salir de todos los métodos públicos. Los métodos deben definir precondiciones y postcondiciones para ayudar a cumplir la invariabilidad de la clase.

