¿Qué es estado, estado mutable y estado inmutable?

32

Esta es una pregunta para novatos, pero no pude encontrar una respuesta a prueba de novatos en Google.

¿Qué quieren decir las personas cuando dicen 'estado': en la programación en general y en la programación OO específicamente?

Además, ¿qué es el estado mutable e inmutable, de nuevo, generalmente en programación y también específicamente en OOP?

Aviv Cohn
fuente
44
Compartir su investigación ayuda a todos . Cuéntanos qué has probado y por qué no satisfizo tus necesidades. Esto demuestra que te has tomado el tiempo para tratar de ayudarte a ti mismo, nos salva de reiterar respuestas obvias y, sobre todo, te ayuda a obtener una respuesta más específica y relevante. También vea Cómo preguntar
mosquito

Respuestas:

46

Tiene estado cuando asocia valores (números, cadenas, estructuras de datos complejas) a una identidad y un punto en el tiempo.

Por ejemplo, el número 10 por sí solo no representa ningún estado: es solo un número bien definido y siempre será él mismo: el número natural 10. Como otro ejemplo, la cadena "HOLA" es una secuencia de cinco caracteres, y se describe completamente por los caracteres que contiene y la secuencia en que aparecen. En cinco millones de años a partir de ahora, la cadena "HOLA" seguirá siendo la cadena "HOLA": un valor puro.

Para tener un estado, debes considerar un mundo en el que estos valores puros estén asociados a algún tipo de entidades que poseen una identidad . La identidad es una idea primitiva: significa que puede distinguir dos cosas independientemente de cualquier otra propiedad que puedan tener. Por ejemplo, dos autos del mismo modelo, del mismo color, ... son dos autos diferentes.

Dadas estas cosas con identidad, puede adjuntarles propiedades, descritas por valores puros. Por ejemplo, mi auto tiene la propiedad de ser azul. Puede describir este hecho asociando el par

("colour", "blue")

a mi auto El par ("color", "azul") es un valor puro que describe el estado de ese automóvil en particular.

El estado no solo está asociado a una entidad particular, sino también a un punto particular en el tiempo. Entonces, puedes decir que hoy mi auto tiene estado

("colour", "blue")

Mañana lo tendré repintado en negro y el nuevo estado será

("colour", "black")

Tenga en cuenta que el estado de una entidad puede cambiar, pero su identidad no cambia por definición. Bueno, mientras exista la entidad, por supuesto: se puede crear y destruir un automóvil, pero mantendrá su identidad durante toda su vida. No tiene sentido hablar sobre la identidad de algo que aún no existe / nunca más.

Si los valores de las propiedades adjuntas a una entidad dada cambian con el tiempo, usted dice que el estado de esa entidad es mutable . De lo contrario, dices que el estado es inmutable .

La implementación más común es almacenar el estado de una entidad en algún tipo de variables (variables globales, variables miembro de objeto), es decir, almacenar la instantánea actual de un estado. El estado mutable se implementa utilizando la asignación: cada operación de asignación reemplaza la instantánea anterior por una nueva. Esta solución normalmente usa ubicaciones de memoria para almacenar la instantánea actual. Sobrescribir una ubicación de memoria es una operación destructiva que reemplaza una instantánea con una nueva. ( Aquí puede encontrar una charla interesante sobre este enfoque de programación orientado al lugar ).

Una alternativa es ver los estados subsiguientes (historial) de una entidad como una secuencia (posiblemente secuencia infinita) de valores, ver, por ejemplo, el Capítulo 3 del SICP . En este caso, cada instantánea se almacena en una ubicación de memoria diferente, y el programa puede examinar diferentes instantáneas al mismo tiempo. Las instantáneas no utilizadas se pueden recolectar basura cuando ya no se necesitan.

Ventajas / desventajas de los dos enfoques.

  • El Enfoque 1 consume menos memoria y permite construir una nueva instantánea de manera más eficiente ya que no implica copia.
  • El enfoque 1 empuja implícitamente el nuevo estado a todas las partes de un programa que tiene una referencia al mismo, el enfoque 2 necesitaría algún mecanismo para enviar una instantánea a sus observadores, por ejemplo, en forma de un evento.
  • El Enfoque 2 puede ayudar a prevenir errores de estado inconsistentes (por ejemplo, actualizaciones de estado parciales): al definir una función explícita que produce un nuevo estado a partir de uno antiguo, es más fácil distinguir entre instantáneas producidas en diferentes momentos.
  • El Enfoque 2 es más modular, ya que permite producir fácilmente vistas sobre el estado que son independientes del estado mismo, por ejemplo, utilizando funciones de orden superior como mapy filter.
Giorgio
fuente
1
Tenga en cuenta que los objetos no son las únicas cosas con estado. Si un programa usa variables globales (mutables), se dice que el programa en sí tiene estado. Del mismo modo, si una función tiene una variable que recuerda valores a través de llamadas a funciones, la función tiene estado.
Doval
2
@Doval: Puedes pensar en el estado global como el estado de un objeto mundial global. Hasta donde yo sé, esta vista se usa, por ejemplo, en Ruby. Una función que recuerda el estado es isomórfica para un objeto con un solo método. La idea básica común es que asocie valores a identidades o lugares, es decir, que ciertas cosas pueden contener valores (posiblemente valores mutables) pero retener su identidad.
Giorgio
3
Claro, estoy de acuerdo en principio. Solo me estoy asegurando de que Prog entienda que la capacidad de estado no es algo exclusivo de OOP. No creo que la línea de pensamiento "todo es un objeto" sea natural.
Doval
@Doval: mencionó funciones con estado que recuerdan valores en diferentes llamadas. Un ejemplo que se me ocurre son las variables locales estáticas en C. Otro ejemplo son los cierres (funciones que capturan variables definidas en su contexto). Los cierres son algo duales a los objetos: un cierre es un objeto con exactamente un método, mientras que un objeto es una colección de cierres definidos sobre las mismas variables. Probablemente ya sepas todo esto, pero quería resumirlo aquí. En general, puede almacenar el estado en alguna ubicación de memoria y acceder a él utilizando diferentes mecanismos, como señaló.
Giorgio
11

El estado es simplemente información sobre algo guardado en la memoria.

Como un simple ejercicio de orientación a objetos, piense en una clase como un cortador de galletas y en las galletas como objetos. Puede crear una cookie (instanciar un objeto) usando el cortador de galletas (clase). Digamos que una de las propiedades de la cookie es su color (que se puede cambiar usando colorante para alimentos). El color de esa cookie es parte de su estado, al igual que las otras propiedades.

El estado mutable es un estado que se puede cambiar después de crear el objeto (cookie). El estado inmutable es un estado que no se puede cambiar.

Los objetos inmutables (para los cuales no se puede cambiar ninguno de los estados) se vuelven importantes cuando se trata de concurrencia, la capacidad de más de un procesador en su computadora para operar en ese objeto al mismo tiempo. La inmutabilidad garantiza que puede confiar en que el estado sea estable y válido durante la vida útil del objeto.

En general, el estado de un objeto se mantiene en "variables privadas o miembros" y se accede a él a través de "propiedades" o métodos getter / setter.

Robert Harvey
fuente
3
Para el beneficio de Prog, el hecho de que un valor nunca cambie también es importante porque es mucho más fácil razonar. Se puede usar en tantas funciones / métodos como desee y sabe que no pueden cambiarlo. Con el estado mutable, debe realizar un seguimiento del historial de cómo se ha utilizado ese objeto para determinar cuál es su valor ahora . Esa es una sobrecarga mental innecesaria si hacer que sea inmutable no complica el programa.
Doval
Gracias por responder. Entonces, básicamente, en OOP, cuando alguien dice 'estado', ¿generalmente significan "variables miembro de un objeto"? Si es así, entonces "estado mutable" son variables públicas, o más comunes en OOP, variables privadas que se pueden cambiar a través de métodos de establecimiento, mientras que "estado inmutable" son simplemente variables miembro privadas.
Aviv Cohn
1
La inmutabilidad se puede simular simplemente nunca escribiendo a los miembros privados de un objeto una vez que se rellenan con valores iniciales. Inmutabilidad puede forzada usando un número de métodos: no proporcionar un método setter, requiriendo el valor inicial para ser establecido mediante un parámetro de constructor, escribiendo en un estilo funcional, utilizando constantes, etc.
Robert Harvey
1
Pienso en el estado como el valor de alguna propiedad de alguna entidad. "Enviado" es un estado. Así es la "tasa de impuestos". El peso de algo es un estado. Si está actualmente despierto o dormido es un estado. El color de algo es un estado. Información significativa sobre algo, guardada en algún tipo de memoria de la computadora.
Robert Harvey
1
En muchos idiomas, la inmutabilidad puede hacerse cumplir declarando las variables miembro como "const" o "final". Dichas variables solo pueden ser inicializadas por el constructor. No asuma que las variables privadas son inmutables; aún pueden ser modificadas por las funciones miembro (métodos) de la clase.
Simon B
7

Creo que el término "estado" (en oposición a un tipo concreto de estado, como "variable miembro") es más útil cuando se compara una API con estado con una sin estado. Intentar definir "estado" sin mencionar las API es un poco como tratar de definir "variable" o "función" sin mencionar los lenguajes de programación; La mayoría de las respuestas correctas solo tienen sentido para las personas que ya saben lo que significan las palabras.

Stateful vs Stateless

  • Una API con estado es aquella que "recuerda" qué funciones ha llamado hasta ahora y con qué argumentos, por lo que la próxima vez que llame a una función utilizará esa información. La parte "recordar" a menudo se implementa con variables miembro, pero esa no es la única forma.
  • Una API sin estado es aquella en la que cada llamada a una función depende únicamente de los argumentos que se le pasan, y nada más.

Por ejemplo, OpenGL es probablemente la API con más estado que conozco. Si puedo simplificarlo excesivamente por un momento, podríamos decir que se parece a esto:

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

Casi todas las funciones solo se usan para pasar en algunos de los estados que OpenGL necesita recordar, luego al final se llama una función anticlimáticamente simple para hacer todo el dibujo.

Una versión sin estado de OpenGL (simplificado en exceso) probablemente se parecería más a esto:

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

A menudo escuchará a la gente decir que las API con menos estado son más fáciles de razonar. Si puede mantener el argumento bajo control, generalmente estoy de acuerdo con eso.

Mutable vs inmutable

Hasta donde sé, esta distinción solo es significativa cuando se puede especificar un estado inicial . Por ejemplo, usando constructores de 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;

Sería difícil implementar una clase de ventana que no "recuerde" de qué tamaño es, pero puede decidir si el usuario debería poder cambiar el tamaño de una ventana después de crearla.

PD: en OOP es cierto que "estado" generalmente significa "variables miembro", pero puede ser mucho más que eso. Por ejemplo, en C ++, un método puede tener una variable estática, y las lambdas pueden convertirse en cierres al capturar variables. En ambos casos, esas variables persisten en múltiples llamadas a la función y, por lo tanto, probablemente califican como estado. Las variables locales en una función regular también pueden considerarse estado dependiendo de cómo se usan (las que tengo en main () a menudo cuentan).

Ixrec
fuente
IMPRESIONANTE respuesta. Muchas gracias, realmente me ayudaste a entender esto rápido. Poco sabía, he estado trabajando con esto durante mucho tiempo y no sabía cómo se llamaba.
the_endian
2

En palabras simples

El diccionario dice:

a. Una condición o modo de ser, con respecto a las circunstancias.

  1. estado: la forma en que algo es con respecto a sus atributos principales;

El estado de algo es el conjunto de valores que tienen sus atributos en un momento dado.

En OOP, el estado de un objeto es una instantánea de los valores de sus atributos en un momento dado.

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

El estado es que su color es azul, su precio es 100 y su tamaño es pequeño.

Si luego lo haces:

t.setColor("red");

Cambia uno de sus atributos pero también cambia el estado en su totalidad ya que el objeto ya no es el mismo que era.

A veces, las clases se diseñan para que los valores de sus propiedades no puedan cambiarse después de crearse. Todos los valores de sus propiedades se pasan al constructor o se leen desde alguna fuente, como una base de datos o un archivo, pero no hay forma de cambiar esos valores después de ese momento, ya que no hay métodos "setter", ni ninguna otra forma de cambiando los valores dentro del objeto.

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.

Eso se llama un estado que no se puede cambiar de mutado. Todo lo que puede hacer es destruir el objeto, crear uno nuevo y asignarlo a la misma referencia o 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
fuente