State (patrón de diseño)
# State (patrón de diseño)

El patrón de diseño State se utiliza cuando el comportamiento de un objeto cambia dependiendo del estado del mismo. Por ejemplo: una alarma puede tener diferentes estados, como desactivada, activada, en configuración. Definimos una interfaz Estado_Alarma, y luego definimos los diferentes estados.

# State (patrón de diseño)
## Introducción

En determinadas ocasiones, cuando el contexto en el que se está desarrollando requiere que un objeto tenga diferentes comportamientos según el estado en que se encuentra, resulta complicado poder manejar el cambio de comportamientos y los estados de dicho objeto, todos dentro del mismo bloque de código. El patrón State propone una solución a esta complicación, creando básicamente, un objeto por cada estado posible del objeto que lo llama.

# State (patrón de diseño)
## Propósito

Permite a un objeto alterar su comportamiento dependiendo de su estado interno.

# State (patrón de diseño)
## Motivación

El patrón State está motivado por aquellos objetos en que, según su estado actual, varía su comportamiento ante los diferentes mensajes. Como ejemplo se toma una clase TCPConnection que representa una conexión de red, un objeto de esta clase tendrá diferentes respuestas según su estado (Listening, Closed o Established). Por ejemplo la invocación al método Open de un objeto de la clase TCPConnection diferirá su comportamiento si la conexión se encuentra en Closed o en Established.

# State (patrón de diseño)
## Problema

Existe una extrema complejidad en el código cuando se intenta administrar comportamientos diferentes según una cantidad de estados diferentes. Asimismo el mantenimiento de este código se torna dificultoso, e incluso se puede llegar en algunos casos puntuales a la incongruencia de estados actuales por la forma de implementación de los diferentes estados en el código (por ejemplo con variables para cada estado).

# State (patrón de diseño)
## Consideraciones

Se debe contemplar la complejidad comparada con otras soluciones.

# State (patrón de diseño)
## Solución

Se implementa una clase para cada estado diferente del objeto y el desarrollo de cada método según un estado determinado. El objeto de la clase a la que le pertenecen dichos estados resuelve los distintos comportamientos según su estado, con instancias de dichas clases de estado. Así, siempre tiene presente en un objeto el estado actual y se comunica con este para resolver sus responsabilidades.
La idea principal en el patrón State es introducir una clase abstracta TCPState que representa los estados de la conexión de red y una interfaz para todas las clases que representan los estados propiamente dichos. Por ejemplo la clase TCPEstablished y la TCPClose implementan responsabilidades particulares para los estados establecido y cerrado respectivamente del objeto TCPConnection. La clase TCPConnection mantiene una instancia de alguna subclase de TCPState con el atributo state representando el estado actual de la conexión. En la implementación de los métodos de TCPConnection habrá llamadas a estos objetos representados por el atributo state para la ejecución de las responsabilidades, así según el estado en que se encuentre, enviará estas llamadas a un objeto u otro de las subclases de TCPState.

# State (patrón de diseño)
## Estructura UML

* Diagrama UML del patrón de diseño State

# State (patrón de diseño)
## Participantes

* Context(Contexto): Este integrante define la interfaz con el cliente. Mantiene una instancia de ConcreteState (Estado Concreto) que define su estado actual
* State (Estado):Define una interfaz para el encapsulamiento de la responsabilidades asociadas con un estado particular de Context.
* Subclase ConcreteState:Cada una de estas subclases implementa el comportamiento o responsabilidad de Context.
El Contexto (Context) delega el estado específico al objeto ConcreteState actual Un objeto Context puede pasarse a sí mismo como parámetro hacia un objeto State. De esta manera la clase State puede acceder al contexto si fuese necesario. Context es la interfaz principal para el cliente. El cliente puede configurar un contexto con los objetos State. Una vez hecho esto, los clientes no tendrán que tratar con los objetos State directamente. Tanto el objeto Context como los objetos de ConcreteState pueden decidir el cambio de estado.

# State (patrón de diseño)
## Colaboraciones

El patrón State puede utilizar el patrón Singleton cuando requiera controlar que exista una sola instancia de cada estado. Lo puede utilizar cuando se comparten los objetos como Flyweight existiendo una sola instancia de cada estado y ésta es compartida con más de un objeto.

# State (patrón de diseño)
## ¿Cómo funciona?

La clase Context envía mensajes a los objetos ConcreteState dentro de su código para brindarle a estos la responsabilidad que debe cumplir el objeto Context. Así el objeto Context va cambiando las responsabilidades según el estado en que se encuentra, puesto que también cambia de objeto ConcreteState al hacer dicho cambio de estado.

# State (patrón de diseño)
## ¿Cuándo emplearlo?

Está apuntado a cuando un determinado objeto tiene diferentes estados y también distintas responsabilidades según el estado en que se encuentre en determinado instante. También puede utilizarse para simplificar casos en los que se tiene un complicado y extenso código de decisión que depende del estado del objeto

# State (patrón de diseño)
## Ventajas y desventajas

Se encuentran las siguientes ventajas:
* Se localizan fácilmente las responsabilidades de los estados específicos, dado que se encuentran en las clases que corresponden a cada estado. Esto brinda una mayor claridad en el desarrollo y el mantenimiento posterior. Esta facilidad la brinda el hecho que los diferentes estados están representados por un único atributo (state) y no envueltos en diferentes variables y grandes condicionales.
* Hace los cambios de estado explícitos puesto que en otros tipos de implementación los estados se cambian modificando valores en variables, mientras que aquí al estar representado cada estado.
* Los objetos State pueden ser compartidos si no contienen variables de instancia, esto se puede lograr si el estado que representan esta enteramente codificado en su tipo. Cuando se hace esto estos estados son Flyweights sin estado intrínseco.
* Facilita la ampliación de estados
* Permite a un objeto cambiar de clase en tiempo de ejecución dado que al cambiar sus responsabilidades por las de otro objeto de otra clase la herencia y responsabilidades del primero han cambiado por las del segundo.
Se encuentran la siguiente desventaja:
* Se incrementa el número de subclases.

# State (patrón de diseño)
## Conclusiones

El patrón no indica exactamente dónde definir las transiciones de un estado a otro. Existen dos formas de solucionar esto: Una es definiendo estas transiciones dentro de la clase contexto, la otra es definiendo estas transiciones en las subclases de State. Es más conveniente utilizar la primera solución cuando el criterio a aplicar es fijo, es decir, no se modificará. En cambio la segunda resulta conveniente cuando este criterio es dinámico, el inconveniente aquí se presenta en la dependencia de código entre las subclases.
También hay que evaluar en la implementación cuándo crear instancias de estado concreto distintas o utilizar la misma instancia compartida. Esto dependerá si el cambio de estado es menos frecuente o más frecuente respectivamente.