web-dev-qa-db-fra.com

Qu'est-ce qu'un État, un État mutable et un État immuable?

C'est une question pour les débutants, mais je n'ai pas trouvé de réponse suffisante pour les débutants sur Google.

Que veulent dire les gens quand ils disent "état" - dans la programmation en général, et dans la programmation OO en particulier?

De plus, qu'est-ce qu'un état mutable et immuable - encore une fois, généralement en programmation et aussi spécifiquement en POO?

34
Aviv Cohn

Vous avez un état lorsque vous associez des valeurs (nombres, chaînes, structures de données complexes) à une identité et un point dans le temps.

Par exemple, le nombre 10 en lui-même ne représente aucun état: c'est juste un nombre bien défini et sera toujours lui-même: le nombre naturel 10. Comme autre exemple, la chaîne "BONJOUR" est une séquence de cinq caractères, et il est complètement décrit par les caractères qu'il contient et la séquence dans laquelle ils apparaissent. Dans cinq millions d'années, la chaîne "HELLO" sera toujours la chaîne "HELLO": une valeur pure.

Pour avoir un état, vous devez considérer un monde dans lequel ces valeurs pures sont associées à une sorte d'entités qui possèdent une identité . L'identité est une idée primitive: cela signifie que vous pouvez distinguer deux choses indépendamment de toute autre propriété qu'elles peuvent avoir. Par exemple, deux voitures du même modèle, de même couleur, ... sont deux voitures différentes.

Étant donné ces éléments d'identité, vous pouvez leur associer des propriétés, décrites par des valeurs pures. Par exemple, ma voiture a la propriété d'être bleue. Vous pouvez décrire ce fait en associant la paire

("colour", "blue")

à ma voiture. La paire ("couleur", "bleu") est une valeur pure décrivant l'état de cette voiture particulière.

L'État n'est pas seulement associé à une entité particulière, mais également à un moment particulier. Donc, vous pouvez dire qu'aujourd'hui, ma voiture a un état

("colour", "blue")

Demain je vais le repeindre en noir et le nouvel état sera

("colour", "black")

Notez que l'état d'une entité peut changer, mais son identité ne change pas par définition. Eh bien, tant que l'entité existe, bien sûr: une voiture peut être créée et détruite, mais elle gardera son identité tout au long de sa vie. Il n'est pas logique de parler de l'identité de quelque chose qui n'existe pas encore/plus.

Si les valeurs des propriétés attachées à une entité donnée changent au fil du temps, vous dites que l'état de cette entité est mutable . Sinon, vous dites que l'état est immuable .

L'implémentation la plus courante consiste à stocker l'état d'une entité dans une sorte de variables (variables globales, variables de membre d'objet), c'est-à-dire à stocker l'instantané actuel d'un état. L'état mutable est ensuite implémenté à l'aide de l'affectation: chaque opération d'affectation remplace l'instantané précédent par un nouveau. Cette solution utilise normalement des emplacements de mémoire pour stocker l'instantané actuel. Le remplacement d'un emplacement mémoire est une opération destructrice qui remplace un instantané par un nouveau. ( Ici vous pouvez trouver une discussion intéressante sur cette approche programmation orientée lieu.)

Une alternative consiste à visualiser les états ultérieurs (historique) d'une entité comme un flux (éventuellement séquence infinie) de valeurs, voir par ex. Chapitre 3 du SICP . Dans ce cas, chaque instantané est stocké dans un emplacement mémoire différent et le programme peut examiner différents instantanés en même temps. Les instantanés inutilisés peuvent être récupérés lorsqu'ils ne sont plus nécessaires.

Avantages/inconvénients des deux approches

  • L'approche 1 consomme moins de mémoire et permet de construire un nouvel instantané plus efficacement car elle n'implique aucune copie.
  • L'approche 1 pousse implicitement le nouvel état à toutes les parties d'un programme qui y font référence, l'approche 2 aurait besoin d'un mécanisme pour transmettre un instantané à ses observateurs, par ex. sous la forme d'un événement.
  • L'approche 2 peut aider à prévenir les erreurs d'état incohérentes (par exemple, les mises à jour d'état partielles): en définissant une fonction explicite qui produit un nouvel état à partir d'un ancien, il est plus facile de distinguer les instantanés produits à différents moments.
  • L'approche 2 est plus modulaire en ce qu'elle permet de produire facilement des vues sur l'état qui sont indépendantes de l'état lui-même, par ex. en utilisant des fonctions d'ordre supérieur telles que map et filter.
48
Giorgio

L'État est simplement une information sur quelque chose gardé en mémoire.

Comme un simple exercice d'orientation d'objet, considérez une classe comme un emporte-pièce et les cookies comme des objets. Vous pouvez créer un cookie (instancier un objet) à l'aide de l'emporte-pièce (classe). Disons que l'une des propriétés du cookie est sa couleur (qui peut être modifiée en utilisant du colorant alimentaire). La couleur de ce cookie fait partie de son état, tout comme les autres propriétés.

L'état mutable est un état qui peut être modifié après avoir créé l'objet (cookie). L'état immuable est un état qui ne peut pas être modifié.

Les objets immuables (pour lesquels aucun de l'état peut être modifié) deviennent importants lorsque vous traitez simultanéité la possibilité pour plus d'un processeur de votre ordinateur de fonctionner sur ce objet en même temps. L'immuabilité garantit que vous pouvez compter sur l'état pour qu'il soit stable et valide pour la durée de vie de l'objet.

En général, l'état d'un objet est conservé dans des "variables privées ou membres" et accessible via des "propriétés" ou des méthodes getter/setter.

11
Robert Harvey

Je pense que le terme "état" (par opposition à un type d'état concret tel que "variable membre") est plus utile lorsque l'on compare une API avec état à une API sans état. Essayer de définir "état" sans mentionner les API, c'est un peu comme essayer de définir "variable" ou "fonction" sans mentionner les langages de programmation; la plupart des bonnes réponses n'ont de sens que pour les personnes qui connaissent déjà la signification des mots.

Avec état vs apatride

  • Une avec état API est une API qui "se souvient" des fonctions que vous avez appelées jusqu'à présent et avec quels arguments, donc la prochaine fois que vous appellerez une fonction, elle utilisera ces informations. La partie "souvenir" est souvent implémentée avec des variables membres, mais ce n'est pas le seul moyen.
  • Une API sans état est celle où chaque appel de fonction dépend uniquement des arguments qui lui sont passés, et rien d'autre.

Par exemple, OpenGL est probablement l'API la plus dynamique que je connaisse. Si je peux simplifier ridiculement un instant, nous pourrions dire qu'il ressemble à ceci:

glSetCurrentVertexBufferArray(vba1);
glSetCurrentVertexBufferObject(vbo1);
glSetCurrentVertexShader(vert1);
glSetCurrentFragmentShader(frag1);
// a dozen other things
glActuallyDrawStuffWithCurrentState(GL_TRIANGLES);

Presque chaque fonction est juste utilisée pour passer dans certains états dont OpenGL doit se souvenir, puis à la fin, vous appelez une fonction simple et anti-limitative pour faire tout le dessin.

Une version sans état d'OpenGL (simplifiée à l'extrême) ressemblerait probablement davantage à ceci:

glActuallyDrawStuff(vba1, vbo1, vert1, frag1, /* a dozen other things */, GL_TRIANGLES);

Vous entendrez souvent des gens dire que les API avec moins d'état sont plus faciles à raisonner. Si vous pouvez contrôler le nombre d'arguments, je suis généralement d'accord avec cela.

Mutable vs immuable

Pour autant que je sache, cette distinction n'a de sens que si vous pouvez spécifier un état initial . Par exemple, en utilisant des constructeurs C++:

// immutable state
ImmutableWindow windowA = new ImmutableWindow(600, 400);
windowA = new ImmutableWindow(800, 600); // to change the size, I need a whole new window

// mutable state
MutableWindow windowB = new MutableWindow(600, 400);
windowB.width = 800; // to change the size, I just alter the existing object
windowB.height = 600;

Il serait difficile d'implémenter une classe de fenêtre qui ne "se souvient" pas de sa taille, mais vous pouvez décider si l'utilisateur doit pouvoir modifier la taille d'une fenêtre après l'avoir créée.

PS Dans OOP il est vrai que "état" habituellement signifie "variables membres", mais cela peut être beaucoup plus que cela. Par exemple, en C++, une méthode peut avoir une variable statique, et les lambdas peuvent devenir des fermetures en capturant des variables. Dans les deux cas, ces variables persistent à travers plusieurs appels à la fonction et sont donc probablement qualifiées de Les variables locales dans une fonction régulière peuvent également être considérées comme des états en fonction de leur utilisation (celles que j'ai dans main () comptent souvent).

7
Ixrec

En termes simples

Le dictionnaire indique:

une. Une condition ou un mode d'être, par rapport aux circonstances.

  1. état - la façon dont quelque chose est par rapport à ses principaux attributs;

L'état de quelque chose est l'ensemble des valeurs que ses attributs ont à un moment donné.

Dans OOP l'état d'un objet est un instantané de la valeur de ses attributs à un moment donné.

Thing t = new Thing();
t.setColor("blue");
t.setPrice(100)
t.setSize("small");

Son état est sa couleur bleue, son prix 100 et sa taille petite.

Si vous le faites plus tard:

t.setColor("red");

Vous modifiez l'un de ses attributs mais vous avez également changé l'état dans son ensemble puisque l'objet n'est plus le même qu'il était.

Parfois, les classes sont conçues pour que les valeurs de leurs propriétés ne puissent pas être modifiées après sa création. Toutes les valeurs de leurs propriétés sont soit transmises au constructeur, soit lues à partir d'une source telle qu'une base de données ou un fichier, mais il n'y a aucun moyen de modifier ces valeurs après ce moment, car il n'y a pas de méthodes "setter", ou tout autre moyen de changer les valeurs à l'intérieur de l'objet.

Thing t = new Thing("red",100,"small");
t.setColor("blue") -->> ERROR, the programmer didn't provide a setter or any other way to change the properties values after initialization.

C'est ce qu'on appelle un état qui ne peut pas être changé ou muté. Tout ce que vous pouvez faire est de détruire l'objet, d'en créer un nouveau et de l'assigner à la même référence ou variable.

Thing t = new Thing("red",100,"small");
t = new Thing("blue",100,"small");
// I had to create a new Thing with another color since this thing is inmutable.
2
Tulains Córdova