Che cos'è lo stato, lo stato mutabile e lo stato immutabile?

31

Questa è una domanda per principianti, ma non sono riuscito a trovare una risposta sufficiente a prova di novizio su Google.

Che cosa significano le persone quando dicono "stato" - nella programmazione in generale, e nella programmazione OO in particolare?

Inoltre, qual è lo stato mutabile e immutabile - di nuovo, generalmente in programmazione e anche specificamente in OOP?

    
posta Aviv Cohn 10.04.2014 - 19:20
fonte

4 risposte

46

Hai uno stato quando si associano valori (numeri, stringhe, strutture dati complesse) a un'identità ea un punto nel tempo.

Ad esempio, il numero 10 di per sé non rappresenta nessuno stato: è solo un numero ben definito e sarà sempre se stesso: il numero naturale 10. Come altro esempio, la stringa "CIAO" è una sequenza di cinque caratteri, ed è completamente descritto dai personaggi che contiene e dalla sequenza in cui appaiono. Tra cinque milioni di anni, la stringa "CIAO" sarà ancora la stringa "CIAO": un valore puro.

Per avere uno stato devi considerare un mondo in cui questi valori puri sono associati a qualche tipo di entità che possiedono un'identità . L'identità è un'idea primitiva: significa che puoi distinguere due cose indipendentemente da altre proprietà che possono avere. Ad esempio, due auto dello stesso modello, dello stesso colore, ... sono due auto diverse.

Considerate queste cose con identità, è possibile associarvi delle proprietà, descritte da valori puri. Ad esempio, la mia macchina ha la proprietà di essere blu. Puoi descrivere questo fatto associando la coppia

("colour", "blue")

alla mia macchina. La coppia ("color", "blue") è un valore puro che descrive lo stato di quella particolare macchina.

Lo stato non è solo associato a una particolare entità, ma anche a un particolare punto temporale. Quindi, oggi puoi dire che la mia macchina ha lo stato

("colour", "blue")

Domani lo rivernerò in nero e il nuovo stato sarà

("colour", "black")

Tieni presente che lo stato di un'entità può cambiare, ma la sua identità non cambia per definizione. Bene, finché esiste l'entità, naturalmente: un'auto può essere creata e distrutta, ma manterrà la sua identità per tutta la sua durata. Non ha senso parlare dell'identità di qualcosa che ancora non esiste più.

Se i valori delle proprietà associate a una data entità cambiano nel tempo, tu dici che lo stato di tale entità è mutabile . Altrimenti, dici che lo stato è immutable .

L'implementazione più comune è quella di memorizzare lo stato di un'entità in una sorta di variabili (variabili globali, variabili membro dell'oggetto), ad esempio per memorizzare lo snapshot corrente di uno stato. Lo stato mutabile viene quindi implementato utilizzando l'assegnazione: ogni operazione di assegnazione sostituisce l'istantanea precedente con una nuova. Questa soluzione utilizza normalmente posizioni di memoria per memorizzare l'istantanea corrente. La sovrascrittura di una posizione di memoria è un'operazione distruttiva che sostituisce un'istantanea con una nuova. ( Qui puoi trovare un interessante discorso su questo approccio programmazione orientata al luogo .)

Un'alternativa è vedere gli stati successivi (storia) di un'entità come uno stream (possibilmente una sequenza infinita) di valori, vedi per es. Capitolo 3 di SICP . In questo caso, ciascuna istantanea viene archiviata in una diversa posizione di memoria e il programma può esaminare diverse istantanee contemporaneamente. Le istantanee non utilizzate possono essere raccolte automaticamente quando non sono più necessarie.

Vantaggi / svantaggi dei due approcci

  • L'approccio 1 consuma meno memoria e consente di costruire una nuova istantanea in modo più efficiente poiché non comporta alcuna copia.
  • L'approccio 1 spinge implicitamente il nuovo stato in tutte le parti di un programma che contiene un riferimento ad esso, l'approccio 2 avrebbe bisogno di un meccanismo per spingere un'istantanea ai suoi osservatori, ad es. sotto forma di un evento.
  • L'approccio 2 può aiutare a prevenire errori di stato inconsistenti (ad es. aggiornamenti di stato parziali): definendo una funzione esplicita che produce un nuovo stato da uno vecchio, è più facile distinguere tra istantanee prodotte in momenti diversi.
  • L'approccio 2 è più modulare in quanto consente di produrre facilmente viste sullo stato che sono indipendenti dallo stato stesso, ad es. utilizzando funzioni di ordine superiore come map e filter .
risposta data 10.04.2014 - 20:17
fonte
11

Lo stato è semplicemente informazioni su qualcosa tenuto in memoria.

Come semplice esercizio di orientamento agli oggetti, pensa a una classe come a un cookie cutter ea cookie come a oggetti. Puoi creare un cookie (creare un'istanza di un oggetto) usando il taglia-biscotti (classe). Diciamo che una delle proprietà del cookie è il suo colore (che può essere modificato usando colorante alimentare). Il colore di quel cookie è parte del suo stato, come lo sono le altre proprietà.

Lo stato mutabile è lo stato che può essere modificato dopo aver creato l'oggetto (cookie). Lo stato immutabile è lo stato che non può essere modificato.

Gli oggetti immutabili (per i quali nessuno dello stato può essere modificato) diventano importanti quando si ha a che fare con concorrenza, la capacità di più di un processore nel computer di operare su quell'oggetto allo stesso tempo. L'immutabilità garantisce di poter contare sullo stato per essere stabile e valido per la vita dell'oggetto.

In generale, lo stato di un oggetto è contenuto in "variabili private o membri" e accessibile tramite "proprietà" o metodi getter / setter.

    
risposta data 10.04.2014 - 19:26
fonte
7

Penso che il termine "stato" (al contrario di un tipo concreto di stato come "variabile membro") sia più utile quando si confronta un'API stateful con una stateless. Cercare di definire "stato" senza menzionare le API è un po 'come cercare di definire "variabile" o "funzione" senza menzionare i linguaggi di programmazione; la maggior parte delle risposte corrette ha senso solo per le persone che sanno già cosa significano le parole.

Stateful vs Stateless

  • Un'API stateful è quella che "ricorda" le funzioni che hai chiamato finora e con quali argomenti, quindi la prossima volta che chiami una funzione utilizzerà queste informazioni. La parte "remembering" è spesso implementata con le variabili membro, ma non è l'unico modo.
  • Un'API stateless è quella in cui ogni chiamata di funzione dipende esclusivamente dagli argomenti passati e nient'altro.

Ad esempio, OpenGL è probabilmente l'API più affermata che io conosca. Se posso ridicolizzarlo in modo ridicolo per un momento, potremmo dire che assomiglia a questo:

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

Quasi tutte le funzioni sono utilizzate per passare alcune delle condizioni in cui OpenGL deve essere ricordato, quindi alla fine si chiama una funzione incredibilmente semplice per fare tutto il disegno.

Una versione stateless di OpenGL (eccessivamente semplificata) probabilmente assomiglia più a questa:

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

Spesso sentirai dire che le API con meno stato sono più facili da ragionare. Se riesci a tenere sotto controllo il conteggio argomento, sono generalmente d'accordo.

Mutevole vs Immutabile

Per quanto ne so, questa distinzione è significativa solo quando puoi specificare uno stato iniziale . Ad esempio, utilizzando i costruttori 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;

Sarebbe difficile implementare una classe di finestre che non "ricorda" di quale dimensione sia, ma puoi decidere se l'utente dovrebbe essere in grado di cambiare le dimensioni di una finestra dopo averlo creato.

P.S. In OOP è vero che "state" di solito significa "variabili membro", ma può essere molto più di questo. Ad esempio, in C ++, un metodo può avere una variabile statica e lambda può diventare chiusure catturando le variabili. In entrambi i casi queste variabili persistono attraverso più chiamate alla funzione e quindi probabilmente si qualificano come stati. Le variabili locali in una funzione normale possono anche essere considerate come dipendono dal modo in cui vengono utilizzate (quelle che ho in main () spesso contano).

    
risposta data 03.01.2015 - 18:22
fonte
2

In parole povere

Il dizionario afferma:

a. A condition or mode of being, as with regard to circumstances.

  1. state - the way something is with respect to its main attributes;

Lo stato di qualcosa è l'insieme di valori che i suoi attributi hanno in un dato momento.

In OOP lo stato di un oggetto è un'istantanea dei valori dei suoi attributi in un dato momento.

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

Lo stato di questo è il suo colore blu, il suo prezzo è 100 e la sua dimensione è ridotta.

Se in seguito lo fai:

t.setColor("red");

Cambia uno dei suoi attributi ma hai anche cambiato lo stato un intero poiché l'oggetto non è più lo stesso di prima.

A volte le classi sono progettate in modo che i valori delle loro proprietà non possano essere modificati dopo la sua creazione. Tutti i valori delle loro proprietà sono passati al costruttore o letti da qualche fonte come un database o un file, ma non c'è modo di cambiare quei valori dopo quel momento, poiché non ci sono metodi "setter", o qualsiasi altro modo di cambiare i valori all'interno dell'oggetto.

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.

Si chiama stato che non può essere modificato di mutato. Tutto quello che puoi fare è distruggere l'oggetto, crearne uno nuovo e assegnarlo allo stesso riferimento o variabile.

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.
    
risposta data 12.02.2016 - 18:49
fonte

Leggi altre domande sui tag