Tengo algunas dudas sobre la siguiente implementación del patrón de estado:Patrón de estado: ¿Cómo deberían pasar los estados de un objeto cuando están involucrados en procesos complejos?
Tengo un objeto Order. Para simplificar, supongamos que tiene una cantidad, idProducto, precio y proveedor. Además, hay un conjunto de estados conocidos en los que la orden puede realizar la transición:
- estado a: el pedido es nuevo, la cantidad debe ser> 0 y debe tener idProducto. El precio y el proveedor aún no están asignados.
- estado b: alguien verifica la orden. Solo se puede cancelar o se puede asignar el proveedor.
- estado c: el proveedor solo puede completar el precio que se cobrará al cliente.
- Estado d: la orden se cancela.
1) Order.isValid() cambia entre estados. Es decir, en estado algunas operaciones no se pueden hacer. Por lo tanto, se ven como:
void setQuantity (int q) {
if (_state.canChangeQuantity()) this.quantity = q;
else arroja una excepción.
}
¿Es correcto o debo hacer que cada estado implemente la operación setQuantity? En ese caso, ¿dónde se almacenará el valor? En el orden, o el estado? En este último caso, tendré que copiar los datos en cada transición de estado.
2) orderProcessor.process (orden) es un objeto que comprueba order.IsValid, transiciona la orden a algún estado, la guarda en la base de datos y realiza algunas acciones personalizadas (en algunos estados, se notifica al administrador, en otros el cliente, etc.). Tengo uno para cada estado.
En StateAOrderProcessor, la persona que verifica el pedido recibe una notificación por correo electrónico y el pedido pasa al estado b.
Ahora, esto empuja las transiciones de estado fuera de la clase de orden. Eso significa que Order tiene un método 'setState', por lo que cada procesador puede cambiarlo. Esto de cambiar el estado desde el exterior no suena bien. ¿Tiene razón?
3) La opción Atherher es mover toda la lógica de validación al procesador de cada estado, pero ahora tengo que rastrear cuándo se cambió la cantidad de una orden para ver si esa operación es válida en el estado actual. Eso me deja el orden algo anémico.
¿Qué opinas chicos? ¿Puede darme algunos consejos para diseñar mejor esto?
Muchas gracias.
Nick
¿Entonces no usaría el patrón de estado? ¿Cómo cumpliría algunos de los requisitos de muestra descritos? No puedo ver la foto. Gracias. – nick2083
La esencia del patrón de estado (al menos cuando leo http://en.wikipedia.org/wiki/State_pattern) es que las mismas capacidades están disponibles en cada estado, y el uso de la herencia para los diferentes estados hace que la polimorfa perfecta sentido. También desea comportamientos adicionales específicos para cada estado. Tiene sentido agregarlos a esas subclases. No veo ninguna violación del concepto de estado en el enfoque que describo. – djna
@djna: Al describirlo, parece que se está perdiendo el objeto de contexto. El objetivo del patrón de estado es que le permite hacer la transición de un objeto vivo (el contexto) de un estado a otro sin copiar todos los datos a un nuevo objeto. Para hacer esto, coloca los datos en la clase de contexto y luego delegue las operaciones en una clase de estado. Esto le permite cambiar el estado después de la creación del objeto. Sin la clase de contexto, solo tiene una jerarquía de herencia antigua simple en lugar del patrón de estado. –