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


32

Questa è una domanda da principiante, ma non sono riuscito a trovare una risposta sufficiente per i principianti su Google.

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

Inoltre, qual è lo stato mutevole e immutabile, ancora una volta, generalmente nella programmazione e nello specifico in OOP?


4
Condividere la tua ricerca aiuta tutti . Dicci cosa hai provato e perché non ha soddisfatto le tue esigenze. Ciò dimostra che hai impiegato del tempo per cercare di aiutarti, ci salva dal ribadire risposte ovvie e soprattutto ti aiuta a ottenere una risposta più specifica e pertinente. Vedi anche Come chiedere
moscerino

Risposte:


46

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

Ad esempio, il numero 10 da solo non rappresenta alcuno 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, e è completamente descritto dai caratteri 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 un qualche tipo di entità che possiede un'identità . L'identità è un'idea primitiva: significa che puoi distinguere due cose indipendentemente dalle altre proprietà che possono avere. Ad esempio, due auto dello stesso modello, stesso colore, ... sono due auto diverse.

Date queste cose con identità, è possibile associare proprietà ad esse, 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 ("colore", "blu") è un valore puro che descrive lo stato di quella particolare auto.

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

("colour", "blue")

Domani lo farò ridipingere in nero e lo sarà il nuovo stato

("colour", "black")

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

Se i valori delle proprietà associate a una determinata entità cambiano nel tempo, si dice che lo stato di tale entità è mutabile . Altrimenti, dici che lo stato è immutabile .

L'implementazione più comune è quella di memorizzare lo stato di un'entità in un qualche tipo di variabili (variabili globali, variabili dei membri dell'oggetto), ovvero memorizzare l' istantanea corrente di uno stato. Lo stato mutabile viene quindi implementato usando l'assegnazione: ogni operazione di assegnazione sostituisce la precedente istantanea 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 discorso interessante su questo approccio di programmazione orientato al luogo.)

Un'alternativa è quella di visualizzare gli stati successivi (storia) di un'entità come un flusso (possibilmente sequenza infinita) di valori, vedere ad esempio il capitolo 3 del SICP . In questo caso, ogni istantanea viene memorizzata in una diversa posizione di memoria e il programma può esaminare contemporaneamente diverse istantanee. Le istantanee non utilizzate possono essere raccolte in modo inutile 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 richiede alcuna copia.
  • L'approccio 1 spinge implicitamente il nuovo stato a tutte le parti di un programma che ne contenga un riferimento, l'approccio 2 avrebbe bisogno di un meccanismo per inviare un'istantanea ai suoi osservatori, ad esempio sotto forma di un evento.
  • L'approccio 2 può aiutare a prevenire errori di stato incoerenti (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 diversi punti nel tempo.
  • L'approccio 2 è più modulare in quanto consente di produrre facilmente viste sullo stato che sono indipendenti dallo stato stesso, ad esempio utilizzando funzioni di ordine superiore come mape filter.

1
Nota che gli oggetti non sono le uniche cose con stato. Se un programma utilizza variabili globali (mutabili), si dice che il programma stesso abbia stato. Allo stesso modo, se una funzione ha una variabile che ricorda i valori tra le chiamate di funzione, la funzione è stateful.
Doval,

2
@Doval: puoi pensare allo stato globale come allo stato di un oggetto mondiale globale. Per quanto ne so, questa vista viene utilizzata ad esempio in Ruby. Una funzione che ricorda lo stato è isomorfa a un oggetto con un solo metodo. L'idea di base comune è che associ valori a identità o luoghi, ovvero che certe cose possono contenere valori (possibilmente valore mutabile) ma conservare la loro identità.
Giorgio,

3
Certo, sono d'accordo in linea di principio. Sto solo assicurandomi che Prog capisca che lo stato non è qualcosa di esclusivo di OOP. Non credo che la linea di pensiero "tutto sia un oggetto" venga naturale.
Doval,

@Doval: hai menzionato funzioni stateful che ricordano i valori attraverso diverse chiamate. Un esempio che mi viene in mente sono le variabili locali statiche in C. Un altro esempio sono le chiusure (funzioni che catturano le variabili definite nel loro contesto). Le chiusure sono in qualche modo doppie rispetto agli oggetti: una chiusura è un oggetto con esattamente un metodo, mentre un oggetto è una raccolta di chiusure definita sulle stesse variabili. Probabilmente sai tutto questo, ma volevo riassumerlo qui. In generale, è possibile memorizzare lo stato in una posizione di memoria e accedervi utilizzando diversi meccanismi, come hai sottolineato.
Giorgio,

11

Lo stato è semplicemente informazione su qualcosa che è tenuto in memoria.

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

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

Gli oggetti immutabili (per i quali nessuno stato può essere modificato) diventano importanti quando si ha a che fare con la concorrenza, la capacità di più di un processore nel computer di operare su quell'oggetto contemporaneamente. L'immutabilità garantisce che è possibile fare affidamento sullo stato affinché sia ​​stabile e valido per la durata dell'oggetto.

In generale, lo stato di un oggetto viene mantenuto in "variabili private o membro" e vi si accede tramite "proprietà" o metodi getter / setter.


3
A vantaggio di Prog, anche il fatto che un valore non cambi mai è importante perché è molto più facile ragionare. Può essere utilizzato in tutte le funzioni / metodi che desideri e sai che non possono modificarlo. Con lo stato mutabile devi tenere traccia della storia di come quell'oggetto è stato usato per capire quale sia il suo valore ora . Questo è inutile sovraccarico mentale se renderlo immutabile non complica il programma.
Doval,

Grazie per aver risposto. Quindi, fondamentalmente, in OOP, quando qualcuno dice "stato", di solito significano "variabili membro di un oggetto"? In tal caso, allora "stato mutabile" sono variabili pubbliche, o più comuni in OOP, variabili private che possono essere modificate tramite metodi setter - mentre "stato immutabile" sono semplicemente variabili membro private?
Aviv Cohn,

1
L'immutabilità può essere simulata semplicemente non scrivendo mai ai membri privati ​​di un oggetto una volta popolati con i valori iniziali. L'immutabilità può essere imposta usando diversi metodi: non fornire un metodo setter, richiedere l'impostazione del valore iniziale usando un parametro costruttore, scrivere in uno stile funzionale, usare costanti, ecc.
Robert Harvey,

1
Penso allo stato come al valore di alcune proprietà di alcune entità. "Spedito" è uno stato. Lo stesso vale per "Aliquota fiscale". Il peso di qualcosa è uno stato. Se sei attualmente sveglio o addormentato è uno stato. Il colore di qualcosa è uno stato. Informazioni significative su qualcosa, contenute in una sorta di memoria del computer.
Robert Harvey,

1
In molte lingue, l'immutabilità può essere imposta dichiarando le variabili membro come "const" o "final". Tali variabili possono essere inizializzate solo dal costruttore. Non dare per scontato che le variabili private siano immutabili: possono ancora essere modificate dalle funzioni (metodi) dei membri della classe.
Simon B,

7

Penso che il termine "stato" (al contrario di un tipo concreto di stato come "variabile membro") sia molto utile quando si confronta un'API con stato con una senza stato. 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 stateful API è uno che "ricorda" quali funzioni avete chiamato finora e con quali argomenti, così la prossima volta che si chiama una funzione che sta andando a utilizzare tali informazioni. La parte "ricordare" è spesso implementata con variabili membro, ma non è l'unico modo.
  • Uno stateless API è quella in cui ogni chiamata di funzione dipende unicamente gli argomenti passati ad esso, e nient'altro.

Ad esempio, OpenGL è probabilmente l'API più stateful che io conosca. Se potessi ridicolmente semplificarlo 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 vengono usate solo per passare in alcuni degli stati che OpenGL deve ricordare, quindi alla fine si chiama una funzione anticlimatica semplice per fare tutto il disegno.

Una versione senza stato di OpenGL (semplificata) sarebbe probabilmente più simile a questa:

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

Sentirai spesso persone dire che le API con meno stato sono più facili da ragionare. Se riesci a tenere sotto controllo l'argomento, in genere sono d'accordo.

Mutevole vs immutabile

Per quanto ne so, questa distinzione è significativa solo quando è possibile specificare uno stato iniziale . Ad esempio, usando 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 finestra che non "ricordi" di quale dimensione sia, ma puoi decidere se l'utente dovrebbe essere in grado di cambiare la dimensione di una finestra dopo averla creata.

PS 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 le lambda possono diventare chiusure acquisendo variabili. In entrambi i casi tali variabili persistono per più chiamate alla funzione e quindi probabilmente si qualificano come stato. Le variabili locali in una funzione regolare possono anche essere considerate stato a seconda del modo in cui vengono utilizzate (quelle che ho in main () spesso contano).


Risposta FANTASTICA. Grazie mille, mi hai davvero aiutato a prenderlo velocemente. Non sapevo, ci sto lavorando da molto tempo e non sapevo come si chiamasse.
the_endian l'

2

In parole profani

Il dizionario afferma:

un. Una condizione o modo di essere, per quanto riguarda le circostanze.

  1. stato - il modo in cui qualcosa è rispetto ai suoi attributi principali;

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

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

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

Lo stato è che il suo colore è blu, il suo prezzo è 100 e la sua dimensione è piccola.

Se in seguito lo fai:

t.setColor("red");

Modifichi uno dei suoi attributi ma hai anche cambiato lo stato nel suo insieme poiché l'oggetto non è più lo stesso di prima.

A volte le classi sono progettate in modo tale che i valori delle loro proprietà non possano essere modificati dopo la sua creazione. Tutti i valori delle loro proprietà vengono passati al costruttore o letti da una 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 cambiando 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.

Questo è chiamato uno stato che non può essere cambiato di mutato. Tutto quello che puoi fare è distruggere l'oggetto, crearne uno nuovo e assimilarlo 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.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.