2011-03-23 7 views
8

Usamos un 'armazón' de State Machine (basado en el patrón de estado) que no expone su estado actual, lo que a veces significa que tengo que hacer cosas de una manera indirecta.¿Debería una máquina de estados exponer su estado actual?

Cuando cuestioné esta decisión de diseño, una de las justificaciones fue que "si necesita conocer el estado actual, lo está utilizando mal".

¿Es esto correcto? No soy muy experto en máquinas de estado.

(lo que pido aquí porque sé que tengo un sesgo inherente contra el Patrón de Estado, que me parece demasiado prolijo.)

Ejemplo

Imagine un sistema que en una de indica que lee dos sensores. Un sensor da un valor numérico, el otro da un booleano que le dice si el primero es "confiable" o no. El sistema genera un valor que es el valor "bueno" actual, o una interpolación (o algún otro cálculo de fantasía) basado en los últimos n buenos valores.

Mi idea sería tener dos subestados: uno "bueno" y el otro "no". Y cuando llega un nuevo valor, me gustaría preguntarle a la máquina de estados cuál es su estado para que sepa cómo manejar la interpolación.

(creo que he respondido a mi pregunta: ¿la solución sería tener un evento NewDataValue(val) en la máquina de estados, que serían solamente hacia delante el valor del estado 'bueno'?)

Respuesta

10

Tengo que estar de acuerdo con la persona que hizo el comentario "usarlo mal".

El objetivo de una máquina de estado es ser una caja negra en la que se bombean los eventos y que hace que ocurran ciertas cosas en función de esos eventos (incluidas las transiciones de estado). Los eventos en sí mismos no deberían depender en absoluto del estado actual de la máquina.

No puedo imaginar una sola situación en la que el evento debe cambiar en función del estado actual (pero no dude que me ilumine si tiene uno).

Un evento será siempre sea lo que sea. Si necesita ser tratado de manera diferente en función del estado actual, eso es un problema para la máquina de estados en sí, no para la bomba de eventos.

De hecho, la idea de cambiar un evento basado en el estado actual no es compatible con la encapsulación.

Las mejores máquinas de estado tienen una forma muy simple:

      +------+ 
         |  | state 
         V  | transitions 
      +---------------+ | 
events --> |    | --+ 
      | state machine | 
effects <-- |    | 
      +---------------+ 

En otras palabras, los eventos se bombea en ella de alguna manera (independiente del estado) y tiene ciertos efectos sobre la base de su estado y los eventos. Y mantiene su propio estado.


En cuanto a la actualización a su pregunta en la que desea manejar la salida de forma diferente en función de si la última lectura era buena o una fórmula basada en los anteriores, me acaba de poner esto en la sección de efectos. Haga que la máquina de estado muestre el valor actual más una indicación de si proviene del sensor o si se calculó.

Luego su código que maneja los efectos puede hacer lo que quiera con esa información. Eso efectivamente le brinda la información que necesita y no rompe la naturaleza de la caja negra.

+0

+1 ¡Tengo que decir que estoy iluminado! – Nilesh

+0

Tenía un ejemplo (vea mi pregunta actualizada), pero creo que lo he respondido yo mismo :) – Benjol

2

Bueno, eso es la verdadera pregunta. ¿Por qué necesita saber el estado actual de la máquina de estado? ¿Qué planeas hacer con eso?

Si lo adivina, es decir, intenta predecir dónde estará la máquina de estado en el futuro en función del estado actual y las nuevas entradas, entonces está ejecutando algo en paralelo a la máquina de estados. No sé si eso es bueno o malo, depende de qué y por qué lo estás haciendo.

Ostensiblemente, la máquina de estado es una caja negra (o en algunos casos, parece una máquina tragamonedas) en la que introduce datos y los extrae.

Como cualquier cosa en la programación, no hay necesidad de que las cosas sean cajas negras opacas. Las cosas siempre pueden ser cajas con caja transparente que tienen ranuras de entrada y ranuras de salida, pero al menos puede ver los engranajes que se ejecutan dentro de ellas. Pero es contrario a la abstracción si está tratando de evitarlo, ya que la máquina de estado está diseñada para encapsular un bloque de lógica.

Por lo tanto, la opacidad de la estructura no es realmente el problema, es lo que intenta hacer con la información si o cuando la obtiene.

+3

me temo que tengo que estar en desacuerdo con que "no hay necesidad de que las cosas sean cajas negras opacas". Esto invariablemente conducirá a la filtración de información y las personas dependerán de esa información. Esas son las mismas personas que te seguirán y te golpearán hasta la muerte cuando trates de hacer que tu código sea más eficiente, rompiendo esa filtración de la que han llegado a depender. No obstante, no hace que la información esté disponible fuera de una estructura de datos a menos que desee estar bloqueado para mantenerla para siempre. – paxdiablo

+0

El hecho de que el proceso esté abierto a la inspección no significa que tenga que estar dañado. Su contrato es explícito, la implementación puede proporcionar luz sobre ese contrato, pero no hace que el contrato sea inviolable. Si otros intentan violar ese contrato, ese es su problema. Es posible que desee llevar a cabo su negocio en habitaciones oscuras, cerradas y llenas de humo. Prefiero más luz solar en la mía. Prefiero una parrilla abierta para poder ver la comida que se está haciendo. Prefiero confiar en mis usuarios que encerrarlos por lo que PUEDEN hacer. Supongo que eliges no confiar en los tuyos. –

2

"si necesita saber el estado actual, lo está utilizando mal". - Eso es correcto.

El estado actual no se puede exponer. Todas las cosas que requieren que actúe de forma diferente, debido a que están en un estado específico, deben ubicarse dentro (y solo allí) de ese estado: como métodos privados llamados de públicos, o como públicos, sin hacer nada (o algo más)) en otros estados. Su "máquina de estado" tiene que funcionar ... y usted, mirando desde fuera, no debería saber por qué.

0

En el diseño de sistemas jerárquicos, normalmente el objeto de nivel superior solo conoce la abstracción del estado del objeto de nivel inferior, p. state_good abstracting (perfecto, aceptable, ...) y state_bad abstracting (failed1, failed2, failed3 ..).

En sistemas no jerárquicos, está bien que un objeto conozca con precisión el estado de otro objeto, especialmente si a los objetos se les asignan tareas diferentes.

-Janusz

Cuestiones relacionadas