Patrones de Diseño, Estado

Anuncio
Fundamentos de Sistemas Computacionales Patrones de Diseño
Maestría en Sistemas Computacionales Estado
Estado
Objetivo
Alterar el comportamiento de un objeto cuando su estado interno
cambia, modificando aparentemente su tipo. El estado del objeto deberá
ser persistente.
Motivación
El patrón estado surge porque en algunas clases es necesario que una
clase modifique su comportamiento de acuerdo cuando se modifica su
estado. Un ejemplo claro se da cuando deseamos establecer utilizar una
clase que nos permite establecer una conexión, la clase puede tener
varios estados diferentes como pueden ser, conectado, desconectado y
conectando.
Nuestra clase de ejemplo debe modificar su comportamiento dependiendo
del estado en el que se encuentre, para poder hacer esto posible la
clase tiene diferentes subclases que se encargan de implementar el
comportamiento específico de la clase, el cual depende del estado en
que se encuentra.
Utilización


Se utiliza cuando necesitamos cambiar el comportamiento de un
objeto dependiendo de su estado.
También se utiliza cuando tenemos grandes cantidades de
segmentos de sentencias condicionales. El patrón estado pone
cada
bloque
de
operaciones
condicionales
en
una
clase
independiente.
Diagrama
Participantes



Contexto. Define la interfaz que utilizarán los clientes y
mantiene una instancia de la subclase que implementa el estado
concreto en que se encuentra la clase.
Estado. Define una interfaz para encapsular el comportamiento
asociado con un estado particular de la clase.
Subclase Concreta por Estado. Cada subclase concreta implementa
el comportamiento asociado a un estado específico de la clase.
1 Alejandro Domingo Velazquez Cruz
Fundamentos de Sistemas Computacionales Patrones de Diseño
Maestría en Sistemas Computacionales Estado
Relación con otros patrones



Manejo de cache. El patrón estado genera instancias específicas
de una clase, las cuáles pueden ser reutilizadas por este
patrón.
Método Fábrica. El método fábrica encapsula la creación de
objetos, pero no tiene un control de ellos después de su
creación.
Singleton. Los objetos que maneja el patrón estado son por lo
general Singletons.
Características
1. Separa el comportamiento asociado a un estado del objeto y lo
divide en varias clases. El patrón estado pone todo el
comportamiento asociado con un estado particular en un objeto.
Debido a que todo el código específico para un estado en
subclases, los nuevos estados y las transiciones pueden ser
añadidas con facilidad definiendo nuevos estados.
2. Hace explícitas las transiciones entre estados. Cuando un objeto
define su estado únicamente por los valores de sus campos, las
transiciones
se
representan
como
simples
operaciones
de
asignación de valores a variables. Tener diferentes objetos para
diferentes estados hace las transiciones explícitas.
3. Los objetos que representan los diversos estados pueden ser
compartidos. Si los objetos que representan a los estados no
tienen variables de instancia, entonces se puede compartir el
objeto estado.
Implementación
Definimos una clase llamada Estado la cual tendrá una variable
estática de su mismo tipo, en la cual guardaremos el estado actual en
el que se encuentra la clase. Tenemos dentro de la clase un método
llamado cambiarEstado que dependiendo de nuestra necesidad modifica su
comportamiento. El cambio en el comportamiento se debe a que regresa
un tipo de subclase diferente, la cual será la responsable del
comportamiento del objeto.
class Estado {
private static Estado estado = new Estado();
public static Estado cambiarEstado(String type) {
if (type.equals("A"))
estado = new A();
if (type.equals("B"))
estado = new B();
return estado;
}
public String toString() {
return "Sin Estado";
}
}
Creamos dos clases A y B que heredan de la clase Estado y son las
responsables de implementar el comportamiento específico de la clase
redefiniendo sus métodos, en nuestro ejemplo únicamente redefinimos el
2 Alejandro Domingo Velazquez Cruz
Fundamentos de Sistemas Computacionales Patrones de Diseño
Maestría en Sistemas Computacionales Estado
método público toString para que al imprimir el objeto podamos ver que
clase se encuentra contenida en él.
class A extends Estado {
public String toString() {
return "Estado A";
}
}
class B extends Estado {
public String toString() {
return "Estado B";
}
}
Para poder probar que nuestra clase guarda el estado en que se
encuentra lo que hacemos es declarar una variable del tipo Estado,
cuya identidad imprimiremos para poder ver que efectivamente es de ese
tipo. Después utilizaremos el método estático cambiarEstado de la
clase para ver como se modifica el comportamiento de la clase. Podemos
verificar el cambio del comportamiento, así como del tipo contenido en
la variable al imprimirlas.
public class ProbarEstado {
public static void main(String[] args) {
Estado estado = new Estado();
System.out.println(estado);
estado = Estado.cambiarEstado("A");
System.out.println(estado);
estado = Estado.cambiarEstado("B");
System.out.println(estado);
}
}
El resultado de la ejecución del código es:
Sin Estado
Estado A
Estado B
Al crear e iniciar la variable no tiene un estado definido porque aún
no se ha utilizado el método cambiar estado. Al usar el método
cambiarEstado con el argumento “A” el comportamiento cambia porque la
subclase contenida es del tipo A, lo mismo pasa cuando le enviamos el
argumento “B”. En caso de que quisiéramos asignar un estado inicial a
la clase bastaría con modificar el constructor para que recibiera un
argumento que defina el estado inicial o que asigne un estado inicial
predefinido.
Ahora veremos otro ejemplo, crearemos una clase llamada Conexión la
cual tiene dos posibles estados Conectado y Desconectado, cuya
funcionalidad es implementada por las subclases del mismo nombre. Para
poder modificar el comportamiento de la clase Conexión lo que hacemos
es declarar dos métodos estáticos llamados conectar y desconectar.
El método conectar devuelve un objeto del tipo Conectado y el método
desconectar devuelve un objeto del tipo Desconectado. Las instancias
concretas de las clases Conectado y Desconectado son las que provee el
funcionamiento específico de la clase, esta característica es
invisible para el cliente porque se comunica a través de la clase
3 Alejandro Domingo Velazquez Cruz
Fundamentos de Sistemas Computacionales Patrones de Diseño
Maestría en Sistemas Computacionales Estado
Conexión utilizando los métodos comunes que fueron redefinidos por las
subclases.
class Conexion {
private static Conexion conexion;
public static Conexion conectar() {
conexion = new Conectado();
return conexion;
}
public static Conexion desconectar() {
conexion = new Desconectado();
return conexion;
}
public void imprimirEstado() {
System.out.println("Sin Estado");
}
}
class Conectado extends Conexion {
public void imprimirEstado() {
System.out.println("Conectado");
}
}
class Desconectado extends Conexion {
public void imprimirEstado() {
System.out.println("Desconectado");
}
}
public class ProbarEstadoConexion {
public static void main(String[] args) {
Conexion conexion = new Conexion();
conexion.imprimirEstado();
conexion = Conexion.conectar();
conexion.imprimirEstado();
conexion = Conexion.desconectar();
conexion.imprimirEstado();
}
}
El resultado de la ejecución da como resultado lo siguiente:
Sin Estado
Conectado
Desconectado
Por lo que podemos ver que el estado del objeto es persistente,
pudiendo cambiar su comportamiento pero manteniendo el estado del
mismo.
4 Alejandro Domingo Velazquez Cruz
Descargar