2012-01-17 21 views
60

busqué en Google el tema, pero además de Wikipedia no encontré ninguna documentación o artículos útiles adicionales.¿Qué es una clase invariante en java?

¿Alguien puede explicarme en palabras simples lo que significa o remitirme a alguna documentación agradable y fácil de entender?

+0

+1 para la pregunta porque la página de Wikipedia tiene un gran ejemplo de algo que no sabía que podía hacer, incluso tiene ejemplos. Sin embargo, su explicación es mejor de lo que podría hacer por ti; es bastante sencillo. – iandisme

+0

https://www.stanford.edu/~pgbovine/programming-with-rep-invariants.htm –

+0

Si está interesado en invariantes w.r.t. Java, tal vez estaría interesado en [contratos para Java] (http://google-opensource.blogspot.com/2011/02/contracts-for-java.html). –

Respuesta

64

No significa nada en particular en referencia a java.

Un invariante de clase es simplemente una propiedad que se mantiene para todas las instancias de una clase, siempre, sin importar lo que haga otro código.

Por ejemplo,

class X { 
    final Y y = new Y(); 
} 

X tiene el invariante de clase que hay una propiedad y y nunca es null y tiene un valor de tipo Y.

class Counter { 
    private int x; 

    public int count() { return x++; } 
} 

falla para mantener dos invariantes importantes

  1. count Eso nunca se devuelve un valor negativo debido a la posible desbordamiento.
  2. Las llamadas a count son estrictamente monótonamente cada vez mayores.

La clase modificada conserva esas dos invariantes.

class Counter { 
    private int x; 

    public synchronized int count() { 
    if (x == Integer.MAX_VALUE) { throw new IllegalStateException(); } 
    return x++; 
    } 
} 

pero no preserva el invariante que llama a count siempre tienen éxito normalmente ausentes (TCB-violaciónes ) porque count podría lanzar una excepción o podría bloquear si un hilo estancado posee el monitor del mostrador.

Cada idioma con clases facilita el mantenimiento de algunas invariantes de clase pero no de otras. Java no es una excepción:

  1. Las clases de Java tienen consistentemente o no tienen propiedades y métodos, por lo que las invariantes de la interfaz son fáciles de mantener.
  2. Las clases de Java pueden proteger sus campos private, por lo que las invariantes que dependen de datos privados son fáciles de mantener.
  3. Las clases de Java pueden ser definitivas, por lo que se pueden mantener las invariantes que dependen de que no exista ningún código que viole una invariante creando una subclase maliciosa.
  4. Java permite valores de null para infiltrarse de muchas maneras, por lo que es difícil mantener invariantes "con un valor real".
  5. Java tiene subprocesos, lo que significa que las clases que no se sincronizan tienen problemas para mantener invariantes que dependen de operaciones secuenciales en un hilo que suceden juntas.
  6. Java tiene excepciones que facilitan el mantenimiento de invariantes como "devuelve un resultado con la propiedad p o no arroja ningún resultado", pero es más difícil mantener invariantes como "siempre devuelve un resultado".

† - Una externalidad o TCB violación es un evento que un diseñador de sistemas asume optimismo no va a ocurrir.

Normalmente acabamos de confiar en que el hardware básico funciona como se anuncia cuando se habla de las propiedades de los lenguajes de alto nivel construidas sobre ellos, y los argumentos que mantienen invariantes no tienen en cuenta la posibilidad de:

  • Un programador que utiliza enlaces de depuración para alterar variables locales cuando un programa se ejecuta de forma que el código no puede.
  • Sus pares no usan la reflexión con setAccessible para modificar las tablas de búsqueda private.
  • Loki altera la física haciendo que su procesador compare incorrectamente dos números.

Para algunos sistemas de nuestra TCB podría incluir sólo las partes del sistema, por lo que podría no suponer que

  • Un administrador o un demonio privilegiada no matarán a nuestro proceso de JVM,

pero podemos suponer que

  • Podemos hacer un punto de control a un sistema de archivos transaccional confiable.

El más alto nivel de un sistema, mayor es su TCB es típicamente, pero las cosas más confiables que usted puede salir de la TCB, los más probable es que su invariantes la titularidad, y el más fiable su sistema será a la larga.

+1

Es "que' count' nunca devuelve el mismo valor dos veces "realmente se considera una clase invariante ? – ruakh

+0

@ruakh, esa es una buena pregunta. No estoy muy seguro. Cosas como la estabilidad de hashCode (para cada instancia i, i.hashCode() no cambia) a menudo se denominan invariantes de clase, lo que requiere un razonamiento sobre los valores devueltos anteriormente, por lo que parece razonable decir que "para cada instancia i, i.count() no en (resultados previos de i.count()) "es un invariante de clase. –

+0

@ruakh ¿No es eso una definición pura? Si postulo tal invariante, ¿por qué no? Sin duda puede ser una garantía interesante e importante (digamos para generar identificaciones únicas). Personalmente, también creo que algo como "si solo el código de un solo subproceso accede a esta clase, son válidas las siguientes propiedades", pero no estoy seguro de si es posible ampliar la definición de tal manera que solo tenga que mantenerse cierta. las condiciones son verdaderas (¡Y teniendo en cuenta la reflexión, es básicamente imposible garantizar algo interesante de lo contrario!) – Voo

8

Son hechos que deben ser ciertos sobre una clase de instancia. Por ejemplo, si una clase tiene una propiedad X e invariante puede ser X debe ser mayor que 0. Que yo sepa, no hay un método incorporado para mantener invariantes, debe hacer que las propiedades sean privadas y asegurarse de que sus implementadores y ejecutores apliquen la propiedad de invarianza.

Hay anotaciones disponibles que pueden comprobar las propiedades utilizando reflexión e interceptores. http://docs.oracle.com/javaee/7/api/javax/validation/constraints/package-summary.html

7

Invariante significa algo que debe ajustarse a sus condiciones independientemente de los cambios o de quien lo use/lo transforme. Es decir, una propiedad de una clase siempre cumple o satisface alguna condición incluso después de pasar por transformaciones mediante el uso de métodos públicos. Entonces, el cliente o usuario de esta clase está asegurado sobre la clase y su propiedad.

Por ejemplo,

  1. condición en argumento de la función es que, siempre debe ser> 0 (mayor que cero) o no debería ser nulo.
  2. minimum_account_balance propiedad de una clase de cuenta estados, no puede ir por debajo de 100. Por lo tanto, todas las funciones públicas deben respetar esta condición y garantizar invariante de clase.
  3. dependencia basada en reglas entre variables, es decir, el valor de una variable depende de otra, por lo que si se modifica, usando alguna regla de corrección, otra también debe cambiar. Esta relación entre 2 variables debe ser preservada. Si no lo hace, entonces invariante es violado.