terminology boucle - Qu'est-ce qu'un invariant de classe dans Java?




python montrer (4)

J'ai recherché sur Google le sujet, mais en dehors de Wikipedia je n'ai trouvé aucune autre documentation ou article utile.

Quelqu'un peut-il m'expliquer en termes simples ce que cela signifie ou me référer à une documentation agréable et facile à comprendre?


Answers

Invariant signifie quelque chose qui devrait coller à ses conditions, peu importe les changements ou ceux qui les utilise / les transforme. C'est-à-dire qu'une propriété d'une classe remplit ou satisfait toujours une condition même après avoir traversé des transformations en utilisant des méthodes publiques. Ainsi, le client ou l'utilisateur de cette classe est assuré de la classe et de ses biens.

Par exemple,

  1. condition sur l'argument de la fonction est cela, il devrait toujours être> 0 (plus grand que zéro) ou ne devrait pas être nul.
  2. La propriété minimum_account_balance d'un état de classe de compte, elle ne peut pas aller au-dessous de 100. Donc toutes les fonctions publiques doivent respecter cette condition et s'assurer que la classe est invariante.
  3. dépendance basée sur des règles entre les variables, c'est-à-dire que la valeur d'une variable dépend d'une autre, donc si l'une change, en utilisant une règle-fixe, l'autre doit également changer. Cette relation entre 2 variables doit être préservée. Si ce n'est pas le cas, alors l'invariant est violé.

Cela ne veut rien dire en particulier en référence à Java.

Un invariant de classe est simplement une propriété qui s'applique à toutes les instances d'une classe, toujours, quel que soit l'autre code.

Par exemple,

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

X a la classe invariant qu'il y a une propriété y et elle n'est jamais null et elle a une valeur de type Y

class Counter {
  private int x;

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

ne parvient pas à maintenir deux invariants importants

  1. Ce count ne renvoie jamais une valeur négative en raison d'un dépassement possible.
  2. Les appels à count sont strictement monotones.

La classe modifiée conserve ces deux invariants.

class Counter {
  private int x;

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

mais ne parvient pas à préserver l'invariant que les appels à count réussissent toujours normalement (violations TCB absentes ) parce que count peut lancer une exception ou bloquer si un thread en interblocage possède le moniteur du compteur.

Chaque langue avec classes facilite le maintien de certains invariants de classe mais pas d'autres. Java n'est pas une exception:

  1. Les classes Java possèdent ou non des propriétés et des méthodes, de sorte que les invariants d'interface sont faciles à maintenir.
  2. Les classes Java peuvent protéger leurs champs private , de sorte que les invariants qui reposent sur des données privées sont faciles à maintenir.
  3. Les classes Java peuvent être définitives, de sorte que les invariants qui reposent sur l'absence de code qui viole un invariant en créant une sous-classe malveillante peuvent être conservés.
  4. Java permet aux valeurs null de se faufiler de plusieurs façons, il est donc difficile de maintenir des invariants «ayant une vraie valeur».
  5. Java a des threads, ce qui signifie que les classes qui ne se synchronisent pas ont du mal à maintenir les invariants qui reposent sur des opérations séquentielles dans un thread qui se passe ensemble.
  6. Java a des exceptions qui le rendent facile à maintenir des invariants comme "retourne un résultat avec la propriété p ou ne renvoie aucun résultat" mais plus difficile de maintenir des invariants comme "retourne toujours un résultat".

† - Une externalité ou une violation de TCB est un événement qu'un concepteur de systèmes suppose avec optimisme que cela n'arrivera pas.

Typiquement, nous avons juste confiance que le matériel de base fonctionne comme annoncé quand on parle de propriétés de langages de haut niveau construits sur eux, et nos arguments que les invariants tiennent ne tiennent pas compte de la possibilité de:

  • Un programmeur utilisant des crochets de débogage pour modifier les variables locales en tant que programme s'exécute de manière non compatible avec le code.
  • Vos homologues n'utilisent pas la réflexion avec setAccessible pour modifier private tables de recherche private .
  • Loki modifiant la physique causant votre processeur à comparer de manière incorrecte deux nombres.

Pour certains systèmes, notre TCB pourrait n'inclure que des parties du système, donc nous ne pouvons pas supposer que

  • Un administrateur ou un démon privilégié ne tueront pas notre processus JVM,

mais nous pourrions supposer que

  • Nous pouvons checkpoint à un système de fichiers transactionnel fiable.

Plus un système est de niveau supérieur, plus son TCB est généralement grand, mais plus les choses que vous pouvez retirer de votre TCB sont peu fiables, plus vos invariants sont susceptibles de contenir, et plus votre système sera fiable à long terme.


Ce sont des faits qui doivent être vrais à propos d'une classe d'instance. Par exemple si une classe a une propriété X et invariant peut être X doit être supérieur à 0. A ma connaissance il n'y a pas de méthode intégrée pour maintenir les invariants, vous devez rendre les propriétés privées et assurez-vous que vos getters et setters appliquent la propriété invariance.

Des annotations sont disponibles qui permettent de vérifier les propriétés à l'aide de la réflexion et des intercepteurs. http://docs.oracle.com/javaee/7/api/javax/validation/constraints/package-summary.html


L'injection de dépendance désigne un moyen (en réalité n'importe quel moyen ) permettant à une partie du code (par exemple, une classe) d'accéder aux dépendances ils peuvent changer ou être annulés librement, ou même être chargés à un autre moment, au besoin)

(et ps, oui, c’est devenu un nom trop surfacé à 25 $ pour un concept plutôt simple) , mes .25centimes





java terminology invariants