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

32

C'est une question de débutant, mais je n'ai pas trouvé de réponse suffisamment novatrice sur Google.

Qu'est-ce que les gens veulent dire quand ils disent «Etat» - dans la programmation en général et dans la programmation OO en particulier?

En outre, quel est l'état mutable et immuable - encore une fois, généralement dans la programmation et aussi spécifiquement dans la POO?

Aviv Cohn
la source
4
Partager vos recherches aide tout le monde . Dites-nous ce que vous avez essayé et pourquoi il ne répondait pas à vos besoins. Cela montre que vous avez pris le temps d'essayer de vous aider, que cela nous évite de répéter des réponses évidentes et, surtout, que cela vous aide à obtenir une réponse plus précise et plus pertinente. Voir aussi Comment demander
Gnat

Réponses:

46

Vous avez l'é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: il s'agit simplement d'un nombre bien défini et sera toujours lui-même: le nombre naturel 10. Autre exemple, la chaîne "HELLO" est une séquence de cinq caractères, et il est complètement décrit par les caractères qu’il contient et par 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é possédant une identité . L'identité est une idée primitive: cela signifie que vous pouvez distinguer deux choses indépendamment de leurs autres propriétés. Par exemple, deux voitures du même modèle, de même couleur, ... sont deux voitures différentes.

Compte tenu de 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.

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

("colour", "blue")

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

("colour", "black")

Notez que l'état d'une entité peut changer, mais que son identité ne change pas par définition. Bien sûr, 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. Cela n'a aucun sens de parler de l'identité de quelque chose qui n'existe pas / plus.

Si les valeurs des propriétés attachées à une entité donnée changent avec le temps, vous indiquez que l'état de cette entité est modifiable . Sinon, vous dites que l'état est immuable .

La mise en œuvre la plus courante consiste à stocker l'état d'une entité dans un certain type de variables (variables globales, variables de membre d'objet), c'est-à-dire à enregistrer l' instantané actuel d'un état. L'état mutable est ensuite mis en œuvre à l'aide d'une affectation: chaque opération d'affectation remplace le cliché précédent par un nouveau. Cette solution utilise normalement des emplacements de mémoire pour stocker l'instantané actuel. Remplacer un emplacement de mémoire est une opération destructive qui remplace un instantané par un nouveau. ( Ici , vous pouvez trouver une discussion intéressante au sujet de cette programmation orientée lieu- approche.)

Une alternative consiste à visualiser les états suivants (historique) d'une entité comme un flux (éventuellement une séquence infinie) de valeurs, voir par exemple le chapitre 3 du SICP . Dans ce cas, chaque instantané est stocké dans un emplacement de mémoire différent et le programme peut examiner différents instantanés en même temps. Les instantanés non utilisés peuvent être ramassé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 il ne nécessite aucune copie.
  • L'approche 1 pousse implicitement le nouvel état à toutes les parties d'un programme comportant une référence, l'approche 2 nécessiterait un mécanisme permettant d'envoyer un instantané à ses observateurs, par exemple 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 partielles d'état): 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 sens qu’elle permet de produire facilement des vues de l’état indépendantes de l’état lui-même, par exemple à l’aide de fonctions d’ordre supérieur telles que mapet filter.
Giorgio
la source
1
Notez que les objets ne sont pas les seules choses avec l'état. Si un programme utilise des variables globales (modifiables), le programme lui-même est réputé avoir un état. De même, si une fonction a une variable qui mémorise des valeurs lors d'appels de fonction, la fonction est avec état.
Doval
2
@Doval: Vous pouvez penser à l'état global en tant qu'état d'un objet mondial global. Autant que je sache, cette vue est utilisée par exemple en Ruby. Une fonction qui se souvient de l'état est isomorphe à un objet avec une seule méthode. L'idée de base commune est d'associer des valeurs à des identités ou à des lieux, c'est-à-dire que certaines choses peuvent contenir des valeurs (éventuellement des valeurs mutables) tout en conservant leur identité.
Giorgio
3
Bien sûr, je suis d'accord en principe. Je m'assure simplement que Prog comprend que l'état de légèreté n'est pas exclusif à la programmation orientée objet. Je ne pense pas que la pensée "tout est objet" vient naturellement.
Doval
@Doval: Vous avez mentionné des fonctions avec état qui mémorisent des valeurs pour différents appels. Un exemple auquel je peux penser est celui des variables locales statiques dans C. Un autre exemple est celui des fermetures (fonctions qui capturent des variables définies dans leur contexte). Les fermetures sont un peu doubles avec les objets: une fermeture est un objet avec exactement une méthode, alors qu'un objet est un ensemble de fermetures définies sur les mêmes variables. Vous savez probablement tout cela mais je voulais le résumer ici. En général, vous pouvez stocker un état dans un emplacement de mémoire et y accéder en utilisant différents mécanismes, comme vous l'avez indiqué.
Giorgio
11

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

En tant qu’exercice simple d’orientation vers les objets, 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 du emporte-pièce (classe). Supposons que l'une des propriétés du cookie est sa couleur (qui peut être modifiée à l'aide d'un colorant alimentaire). La couleur de ce cookie fait partie de son état, de même que les autres propriétés.

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

Les objets immuables (pour lesquels aucun état ne peut être modifié) deviennent importants lorsque vous avez affaire à la simultanéité, c'est-à-dire la possibilité pour plusieurs processeurs de votre ordinateur d'opérer sur cet 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 contenu dans des "variables privées ou membres" et accessible via des méthodes "properties" ou getter / setter.

Robert Harvey
la source
3
Pour le bénéfice de Prog, le fait qu’une valeur ne change jamais est également important car il est beaucoup plus facile de raisonner. Il peut être utilisé dans autant de fonctions / méthodes que vous le souhaitez et vous savez qu'ils ne peuvent pas le changer. Avec l'état mutable, vous devez suivre l'historique de la manière dont cet objet a été utilisé pour déterminer sa valeur actuelle . Cela ne sert à rien de surcharger le mental si le rendre immuable ne complique pas le programme.
Doval
Merci de répondre. Donc, fondamentalement, dans la POO, quand quelqu'un dit «état», ils veulent généralement dire «variables membres d'un objet»? Si tel est le cas, alors 'état mutable' est une variable publique, ou plus commun dans la programmation orientée objet, variables privées pouvant être modifiées via des méthodes de définition - alors que 'état immuable' est simplement une variable membre privée?
Aviv Cohn
1
L’immuabilité peut être simulée en n’écrivant tout simplement jamais aux membres privés d’un objet une fois qu’ils sont renseignés avec les valeurs initiales. L’immuabilité peut être appliquée en utilisant un certain nombre de méthodes: ne pas fournir de méthode de définition, exiger que la valeur initiale soit définie en utilisant un paramètre de constructeur, écrire dans un style fonctionnel, en utilisant des constantes, etc.
Robert Harvey
1
Je pense à l'état comme à la valeur d'une propriété d'une entité. "Expédié" est un état. Il en va de même pour "Taux d'imposition". Le poids de quelque chose est un état. Que vous soyez actuellement éveillé ou endormi est un état. La couleur de quelque chose est un état. Informations utiles sur quelque chose, conservées dans une sorte de mémoire d'ordinateur.
Robert Harvey
1
Dans de nombreuses langues, l'immuabilité peut être appliquée en déclarant les variables membres comme "const" ou "final". De telles variables ne peuvent être initialisées que par le constructeur. Ne supposez pas que les variables privées sont immuables - elles peuvent toujours être modifiées par les propres fonctions membres (méthodes) de la classe.
Simon B
7

Je pense que le terme "état" (par opposition à un type d'état concret tel que "membre") est le plus utile pour comparer une API avec état à une état 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 réponses correctes n'ont de sens que pour les personnes qui savent déjà ce que signifient les mots.

Stateful vs apatride

  • Une API stateful est une API qui "se souvient" des fonctions que vous avez appelées jusqu'à présent et avec quels arguments. Ainsi, la prochaine fois que vous appelez 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 une API où chaque appel de fonction dépend uniquement des arguments qui lui sont transmis, et de rien d'autre.

Par exemple, OpenGL est probablement l’API la plus dynamique que je connaisse. Si je peux ridiculement trop simplifier un instant, on pourrait dire que ça ressemble à quelque chose comme ça:

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

Presque toutes les fonctions sont juste utilisées pour transmettre certains des états qu’OpenGL doit garder à l’esprit, puis à la fin, vous appelez une fonction anticycliquement simple pour effectuer tous les dessins.

Une version sans état d'OpenGL (trop simplifiée) ressemblerait probablement davantage à ceci:

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

Vous entendrez souvent dire que les API avec moins d’état sont plus faciles à raisonner. Si vous pouvez garder l'argument sous contrôle, je suis généralement d'accord avec cela.

Mutable vs Immutable

Pour autant que je sache, cette distinction n'a de sens que lorsque vous pouvez spécifier un état initial . Par exemple, en utilisant les 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 souvienne" 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 En POO, il est vrai que "état" signifie généralement "variables membres", mais cela peut être beaucoup plus que cela. Par exemple, en C ++, une méthode peut avoir une variable statique et lambdas peut devenir des fermetures en capturant des variables. Dans les deux cas, ces variables persistent lors d'appels multiples à la fonction et sont donc probablement qualifiées d'état. Les variables locales dans une fonction régulière peuvent également être considérées en fonction de leur utilisation (celles que j'ai dans main () comptent souvent).

Ixrec
la source
Réponse géniale. Merci beaucoup, vous m'avez vraiment aidé à comprendre cela rapidement. J'ignorais peu, je travaillais avec ça depuis longtemps et je ne savais pas comment ça s'appelait.
the_endian
2

En mots profanes

Le dictionnaire dit:

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

  1. Etat - la manière dont quelque chose se situe par rapport à ses attributs principaux;

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

En POO, 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 bleu, son prix étant 100 et sa taille petite.

Si vous faites plus tard:

t.setColor("red");

Vous modifiez l'un de ses attributs, mais vous modifiez également l'état d'un tout puisque l'objet n'est plus le même.

Parfois, les classes sont conçues pour que les valeurs de leurs propriétés ne puissent plus être modifiées après leur 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’existe aucun moyen de modifier ces valeurs après cet instant, car il n’existe aucune méthode "setter", ni aucun autre moyen de modification. 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.

Cela s'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'associer à 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.
Tulains Córdova
la source