Sei sulla pagina 1di 6

TEMAS AVANZADOS EN DISEÑO DE SOFTWARE

06-Abr/2019

Libro: Head First Design Patterns

State (patrón de diseño)

1. propósito
2. motivación
3. aplicabilidad
4. estructura
5. participantes
6. ventajas y desventajas
7. patrones asociados

State (patrón de diseño)

Este patrón de diseño es útil cuando se necesita que un objeto se comporte de forma diferente dependiendo
del estado interno.

Ejemplo: una alarma puede tener diferentes estados: desactivada, activada, en configuración. Definimos una
interfaz Estado_Alarma, y luego definimos los diferentes estados.

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.

Propósito

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

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.

Ejemplo: Una conexión de red es una implementación de TCP como TCPConnection y la conexión puede estar
en uno de estos estados (abierta, escuchando o cerrada). Cuando un objeto TCPConnection reciba peticiones
de otros objetos debe responder de modo distinto dependiendo de cuál sea su estado.

Página 1 de 6
TEMAS AVANZADOS EN DISEÑO DE SOFTWARE
06-Abr/2019

Aplicaciones

El patrón State se utiliza cuando:

 El comportamiento de un objeto depende de su estado y este puede cambiar en tiempo de ejecución.


 Las operaciones tienen sentencias condicionales anidadas que tratan con los estados. Siendo el estado
normalmente una constante. La idea es mover cada rama de la lógica condicional a una clase aparte.

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).

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.

Página 2 de 6
TEMAS AVANZADOS EN DISEÑO DE SOFTWARE
06-Abr/2019

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 las 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.

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.

¿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.

¿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

Ventajas y desventajas

Página 3 de 6
TEMAS AVANZADOS EN DISEÑO DE SOFTWARE
06-Abr/2019

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.

Ventajas
 Eliminar código if/else
 Reduce duplicación al eliminar código innecesario
 Aumenta la cohesión
 Aumenta las posibilidades de extensión
 Facilita las pruebas de la aplicación

Desventajas
 Demasiado código
 Difícil mantenimiento
 Posibles incongruencias

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.

Conclusiones
 El patrón STATE esta pensado para que el programa sea escalabre y fácil de manejar
 El diseño se puede aplicar a diferentes situaciones
 El patrón ha sido utilizado para la implementación y diseño de software de juegos

Página 4 de 6
TEMAS AVANZADOS EN DISEÑO DE SOFTWARE
06-Abr/2019

Véase también

 Strategy_(patrón_de_diseño)

Este patrón de diseño es parecido al patrón Strategy, en el que se crea un objeto indicando el comportamiento
que deberá tener, pero sin la posibilidad de ser modificado posteriormente.

Patrones de Diseño: State vs Strategy

Lo que es diferente es la intención de lo que se hace. El esquema puede ser igual, pero su sentido es bastante
distinto.
Se usan estados cuando el comportamiento de un objeto depende de algún modo de su situación, cuando su
comportamiento varía de una situación a otra. Imagina un horno microondas (con teclas). El comportamiento
de la tecla de encendido depende de que antes hayas pulsado ya un tiempo y una temperatura. Si estás en el
estado inicial, pulsar encendido no hará nada. Si estás en el estado de ya haber introducido tiempo y potencia,
entonces el mismo botón encenderá el horno. El comportamiento del teclado depende de su estado.
Se usan Estrategias cuando puedes tener diferentes comportamientos para objetos que por lo demás son
iguales. Imagina un horno de nuevo (pero ahora un horno cualquiera). Todos los hornos tienen un botón de
encendido, pero en uno de ellos el botón de encender lo que hace es abrir el gas, en otro lo que hace es
conectar la corriente a la resistencia, en otro activar el generador de microondas, en otro más antiguo pone a
frotar dos palitos (xD)...
Todos los objetos horno son más o menos equivalentes, todos calientan lo que haya dentro, pero la forma de
hacerlo (con gas, con electricidad, con microondas, con un frotador de palitos (xD)) es diferente.
En ambos casos lo que se persigue es encapsular el comportamiento e independizarlo del objeto. Pero en cada
caso lo haces por diferentes razones. En el caso del estado porque ese comportamiento puede ir variando y en
el caso de la estrategia porque podrías reutilizar el objeto genérico simplemente aplicándole otro
comportamiento.
En un caso irás asignando diferentes estados con diferentes comportamientos a lo largo del tiempo. En el otro
asignarás una u otra estrategia al inicializar el objeto y luego (probablemente) ya no más.
Luego hay otras diferencias menores, como que las estrategias en general tienden a ser independientes entre
sí. "ActivarMicroondas" no tiene ninguna relación con "AbrirGas". Los estados en general tienden a ser
bastante dependientes. El estado "TiempoAceptado" y "PotenciaAceptada" suelen compartir variables de
estado (precisamente) y se conocen. Hay una relación que dice que, si estoy en "TiempoAceptado" e
introduzco la potencia, iré a "PotenciaAceptada".

Bibliografía

 https://es.wikipedia.org/wiki/State_(patrón_de_diseño)
 https://informaticapc.com/patrones-de-diseno/state.php (Semáforo)
 https://rootear.com/desarrollo/patron-state
 http://migranitodejava.blogspot.com/2011/06/state.html (Banco)

Página 5 de 6
TEMAS AVANZADOS EN DISEÑO DE SOFTWARE
06-Abr/2019

 http://elblogdepicodev.blogspot.com/2013/08/ejemplo-del-patron-de-diseno-state.html (Compra)
 http://patronesdediseno.blogspot.com/2009/05/patron-state.html (Resumen)
 http://limakuarg.blogspot.com/2012/08/patron-state.html (Estado Civil)
 https://prezi.com/8bpf201zvc62/patron-de-diseno-state/

Página 6 de 6

Potrebbero piacerti anche