¿Cuáles son las diferencias entre el patrón de diseño de la Estrategia y el patrón de diseño del Estado? Estaba leyendo bastantes artículos en la web, pero no pude ver la diferencia claramente.
¿Alguien puede explicar la diferencia en términos simples?
design-patterns
strategy-pattern
state-pattern
Chin Tser
fuente
fuente
Respuestas:
Honestamente, los dos patrones son bastante similares en la práctica, y la diferencia definitoria entre ellos tiende a variar dependiendo de a quién le pregunte. Algunas opciones populares son:
Una implementación "clásica" coincidiría con el Estado o la Estrategia para cada elemento de la lista, pero se encuentra con híbridos que tienen mezclas de ambos. Si un particular es más Estado-y o Estrategia-y es, en última instancia, una cuestión subjetiva.
fuente
getStatus()
método que devolverá diferentes estados según el estado del objeto, pero la persona que llama al método no tiene que codificarse de manera diferente para tener en cuenta cada estado potencial.fuente
La diferencia simplemente radica en que resuelven diferentes problemas:
Sin embargo, los constructos para lograr estos diferentes objetivos son muy similares; ambos patrones son ejemplos de composición con delegación.
Algunas observaciones sobre sus ventajas:
Al utilizar el Estado patrón de la clase (contexto) de retención de estado es relevado de conocimiento de lo que el estado o tipo es y qué estados o tipos que están disponibles. Esto significa que la clase se adhiere al principio de diseño abierto-cerrado (OCP): la clase está cerrada por cambios en los estados / tipos que existen, pero los estados / tipos están abiertos a extensiones.
Al usar el patrón Estrategia , la clase que usa algoritmos (contexto) se libera del conocimiento de cómo realizar una determinada tarea (- el "algoritmo"). Este caso también crea una adherencia al OCP; la clase está cerrada por cambios con respecto a cómo realizar esta tarea, pero el diseño está muy abierto a la adición de otros algoritmos para resolver esta tarea.
Esto probablemente también mejore la adherencia de la clase de contexto al principio de responsabilidad única (SRP). Además, el algoritmo está fácilmente disponible para su reutilización por otras clases.
fuente
Los patrones de diseño no son realmente conceptos "laicos", pero trataré de hacerlo lo más claro posible. Cualquier patrón de diseño puede considerarse en tres dimensiones:
Comparemos Estado y Estrategia.
Problema que resuelve el patrón
El estado se usa en uno de dos casos [GoF book p. 306] :
Si desea asegurarse de que realmente tiene el problema que resuelve el patrón de estado, debería poder modelar los estados del objeto utilizando una máquina de estados finitos . Puede encontrar un ejemplo aplicado aquí .
Cada transición de estado es un método en la interfaz de estado. Esto implica que para un diseño, debe estar bastante seguro acerca de las transiciones de estado antes de aplicar este patrón. De lo contrario, si agrega o elimina transiciones, será necesario cambiar la interfaz y todas las clases que la implementan.
Personalmente no he encontrado este patrón tan útil. Siempre puede implementar máquinas de estados finitos utilizando una tabla de búsqueda (no es una forma OO, pero funciona bastante bien).
La estrategia se utiliza para el siguiente [Libro de GoF p. 316] :
El último caso de dónde aplicar la Estrategia está relacionado con una refactorización conocida como Reemplazar condicional por polimorfismo .
Resumen: Estado y Estrategia resuelven problemas muy diferentes. Si su problema no se puede modelar con una máquina de estados finitos, entonces el patrón de estado probable no es apropiado. Si su problema no se trata de encapsular variantes de un algoritmo complejo, entonces la Estrategia no se aplica.
Estructura estática del patrón
Estado tiene la siguiente estructura de clases UML:
La estrategia tiene la siguiente estructura de clases UML:
Resumen: en términos de estructura estática, estos dos patrones son en su mayoría idénticos. De hecho, las herramientas de detección de patrones como esta consideran que " la estructura de los patrones [...] es idéntica, prohibiendo su distinción por un proceso automático (por ejemplo, sin referirse a información conceptual) " .
Sin embargo, puede haber una diferencia importante si ConcreteStates decide por sí mismo las transiciones de estado (consulte las asociaciones " podría determinar " en el diagrama anterior). Esto da como resultado el acoplamiento entre estados concretos. Por ejemplo (vea la siguiente sección), el estado A determina la transición al estado B. Si la clase Contextual decide la transición al siguiente estado concreto, estas dependencias desaparecen.
Dinámica del patrón.
Como se mencionó en la sección Problema anterior, Estado implica que el comportamiento cambia en tiempo de ejecución dependiendo de algún estado de un objeto. Por lo tanto, se aplica la noción de transición de estado , como se discutió con la relación de la máquina de estados finitos . [GoF] menciona que las transiciones pueden definirse en las subclases de ConcreteState o en una ubicación centralizada (como una ubicación basada en tablas).
Supongamos una máquina de estados finitos simple:
Suponiendo que las subclases deciden la transición de estado (al devolver el siguiente objeto de estado), la dinámica se ve así:
Para mostrar la dinámica de la estrategia , es útil tomar prestado un ejemplo real .
Resumen : cada patrón utiliza una llamada polimórfica para hacer algo según el contexto. En el patrón de estado, la llamada polimórfica (transición) a menudo causa un cambio en el siguiente estado . En el patrón de estrategia, la llamada polimórfica no suele cambiar el contexto (por ejemplo, pagar con tarjeta de crédito una vez no implica que pagará con PayPal la próxima vez). Nuevamente, la dinámica del patrón de estado está determinada por su correspondiente máquina de estado fininte, que (para mí) es esencial para corregir la aplicación de este patrón.
fuente
El Patrón de estrategia implica mover la implementación de un algoritmo de una clase de hosting y colocarlo en una clase separada. Esto significa que la clase de host no necesita proporcionar la implementación de cada algoritmo en sí mismo, lo que probablemente conduzca a un código no limpio.
Los algoritmos de clasificación generalmente se usan como ejemplo, ya que todos hacen el mismo tipo de cosas (ordenar). Si cada algoritmo de clasificación diferente se coloca en su propia clase, el cliente puede elegir fácilmente qué algoritmo usar y el patrón proporciona una manera fácil de acceder a él.
El patrón de estado implica cambiar el comportamiento de un objeto cuando cambia el estado del objeto. Esto significa que la clase de host no proporciona la implementación del comportamiento para todos los diferentes estados en los que puede estar. La clase de host generalmente encapsula una clase que proporciona la funcionalidad que se requiere en un estado dado, y cambia a una clase diferente cuando el estado cambia
fuente
Considere un sistema IVR (Respuesta de voz interactiva) que maneja las llamadas de los clientes. Es posible que desee programarlo para manejar clientes en:
Para manejar esta situación, puede usar un patrón de estado .
Este proceso de conectar a un cliente con un ejecutivo de soporte puede implementarse mediante un Patrón de estrategia en el que los ejecutivos se eligen en función de:
El patrón de estrategia decide " cómo " realizar alguna acción y el patrón de estado decide " cuándo " realizarlas.
fuente
La estrategia representa objetos que "hacen" algo, con los mismos resultados iniciales y finales, pero internamente utilizando diferentes metodologías. En ese sentido, son análogos a representar la implementación de un verbo. El patrón de estado OTOH usa objetos que "son" algo: el estado de una operación. Si bien también pueden representar operaciones en esos datos, son más análogos a la representación de un sustantivo que a un verbo, y están diseñados para máquinas de estado.
fuente
Estrategia: la estrategia es fija y generalmente consta de varios pasos. (La clasificación constituye solo un paso y, por lo tanto, es un mal ejemplo, ya que es demasiado primitivo para comprender el propósito de este patrón). Su rutina "principal" en la estrategia requiere algunos métodos abstractos. Por ejemplo, "Enter Room Strategy", "main-method" es goThroughDoor (), que se ve así: enfoqueDoor (), if (bloqueado ()) openLock (); puerta abierta(); enterRoom (); giro(); closeDoor (); if (wasLocked ()) lockDoor ();
Ahora las subclases de este "algoritmo" general para moverse de una habitación a otra a través de una posible puerta cerrada pueden implementar los pasos del algoritmo.
En otras palabras, la subclasificación de la estrategia no cambia los algoritmos básicos, solo los pasos individuales.
QUE ARRIBA es un patrón de método de plantilla. Ahora coloque los pasos que pertenecen juntos (desbloqueo / bloqueo y apertura / cierre) en sus propios objetos de implementación y delegue en ellos. Por ejemplo, una cerradura con una llave y una cerradura con una tarjeta de código son dos tipos de cerraduras. Delegue de la estrategia a los objetos "Paso". Ahora tienes un patrón de estrategia.
Un patrón de estado es algo completamente diferente.
Tiene un objeto de envoltura y el objeto envuelto. El envuelto es el "estado". Solo se accede al objeto de estado a través de su contenedor. Ahora puede cambiar el objeto envuelto en cualquier momento, por lo que el contenedor parece cambiar su estado, o incluso su "clase" o tipo.
Por ejemplo, tiene un servicio de inicio de sesión. Acepta un nombre de usuario y una contraseña. Solo tiene un método: inicio de sesión (String userName, String passwdHash). En lugar de decidir por sí mismo si se acepta o no un inicio de sesión, delega la decisión a un objeto de estado. Ese objeto de estado generalmente solo verifica si la combinación usuario / pase es válida y realiza un inicio de sesión. Pero ahora puede intercambiar el "Comprobador" por uno que solo permita que los usuarios privilegiados inicien sesión (durante el tiempo de mantenimiento, por ejemplo) o por uno que no permita que nadie inicie sesión. Eso significa que el "verificador" expresa el "estado de inicio de sesión" del sistema.
La diferencia más importante es: cuando has elegido una estrategia, la mantienes hasta que hayas terminado. Eso significa que usted llama a su "método principal" y mientras ese se esté ejecutando, nunca cambiará la estrategia. OTOH en una situación de patrón de estado durante el tiempo de ejecución de su sistema, cambia el estado arbitrariamente como mejor le parezca.
fuente
El patrón de estrategia se utiliza cuando tiene un algoritmo múltiple para una tarea específica y el cliente decide la implementación real que se utilizará en tiempo de ejecución.
Diagrama UML del artículo del patrón de estrategia wiki :
Características clave:
Consulte esta publicación para obtener más información y ejemplos del mundo real:
Ejemplo del mundo real del patrón de estrategia
El patrón de estado permite que un objeto altere su comportamiento cuando cambia su estado interno
Diagrama UML del artículo del patrón wiki State:
Si tenemos que cambiar el comportamiento de un objeto en función de su estado, podemos tener una variable de estado en el Objeto y usar el bloque de condiciones if-else para realizar diferentes acciones en función del estado. El patrón de estado se utiliza para proporcionar una forma sistemática y acoplada por pérdida para lograr esto a través de implementaciones de contexto y estado .
Consulte este artículo de journaldev para obtener más detalles.
Diferencias clave con respecto a la creación de fuentes y artículos de journaldev :
fuente
En lenguaje laico,
en el patrón de Estrategia, no hay estados o todos tienen el mismo estado. Todo lo que uno tiene son diferentes formas de realizar una tarea, como diferentes médicos tratan la misma enfermedad del mismo paciente con el mismo estado de diferentes maneras.
En el patrón de estado, subjetivamente hay estados, como el estado actual del paciente (por ejemplo, temperatura alta o temperatura baja), en función del siguiente curso de acción (prescripción de medicamentos) y un estado puede conducir a otro estado, por lo que hay un estado para declarar dependencia (composición técnicamente).
Si técnicamente tratamos de entenderlo, basándonos en la comparación de código de ambos, podríamos perder la subjetividad de la situación, porque ambos parecen muy similares.
fuente
Ambos patrones delegan a una clase base que tiene varias derivadas, pero es solo en el patrón de estado que estas clases derivadas retienen una referencia a la clase de contexto.
Otra forma de verlo es que el patrón de Estrategia es una versión más simple del patrón de Estado; un subpatrón, si quieres. Realmente depende de si desea que los estados derivados retengan referencias al contexto o no (es decir, si desea que invoquen métodos en el contexto).
Para más información: Robert C Martin (y Micah Martin) responden esto en su libro, "Principios, patrones y prácticas ágiles en C #". ( Http://www.amazon.com/Agile-Principles-Patterns-Practices-C/dp/0131857258 )
fuente
Esta es una pregunta bastante antigua, pero aun así, también estaba buscando las mismas respuestas y esto es lo que he descubierto.
Para el patrón de estado, consideremos un ejemplo del botón Reproducir jugador intermedio. Cuando jugamos, comienza a jugar y hace que el contexto sea consciente de que está jugando. Cada vez que el cliente desea realizar una operación de juego, verifica el estado actual del jugador. Ahora el cliente sabe que el estado del objeto se está reproduciendo a través del objeto de contexto, por lo que llama al método de acciones de objetos de estado de pausa. La parte del cliente que se da cuenta del estado y en qué estado necesita actuar puede automatizarse.
https://www.youtube.com/watch?v=e45RMc76884 https://www.tutorialspoint.com/design_pattern/state_pattern.htm
En el caso del patrón de estrategia, la disposición del diagrama de clase es la misma que la del patrón de estado. El cliente llega a este acuerdo para hacer alguna operación. Es decir, en lugar de los diferentes estados, hay diferentes algoritmos, por ejemplo, diferentes análisis que deben realizarse en el patrón. Aquí los clientes le dicen al contexto qué quiere hacer, qué algoritmo (algoritmo personalizado definido por el negocio) y luego lo realizan.
https://www.tutorialspoint.com/design_pattern/strategy_pattern.htm
Ambos implementan el principio de cierre abierto para que el desarrollador tenga la capacidad de agregar nuevos estados al patrón de estado y al nuevo algoritmo.
Pero la diferencia es lo que se usan, es decir, el patrón de estado utilizado para ejecutar diferentes lógicas basadas en un estado del objeto. Y en un caso de estrategia lógica diferente.
fuente
El estado viene con dependencias un poco dentro de las clases derivadas del estado: como un estado sabe sobre otros estados que vienen después de él. Por ejemplo, el verano llega después del invierno para cualquier estado de temporada, o el estado de entrega después del estado de depósito para compras.
Por otro lado, la estrategia no tiene dependencias como estas. Aquí, cualquier tipo de estado se puede inicializar en función del tipo de programa / producto.
fuente
La diferencia se discute en http://c2.com/cgi/wiki?StrategyPattern . He utilizado el patrón de estrategia para permitir que se elijan diferentes algoritmos dentro de un marco general para analizar datos. A través de eso, puede agregar algoritmos sin tener que cambiar los marcos generales y su lógica.
Un ejemplo típico es que puede tener un marco para optimizar una función. El marco establece los datos y parámetros. El patrón de estrategia le permite seleccionar algoritmos tales como descensos más fuertes, gradientes conjugados, BFGS, etc. sin alterar el marco.
fuente
Tanto la estrategia como el patrón estatal tienen la misma estructura. Si observa el diagrama de clase UML para ambos patrones, se ven exactamente iguales, pero su intención es totalmente diferente. El patrón de diseño de estado se usa para definir y administrar el estado de un objeto, mientras que el patrón de estrategia se usa para definir un conjunto de algoritmos intercambiables y permite al cliente elegir uno de ellos. Por lo tanto, el patrón de estrategia es un patrón impulsado por el cliente, mientras que Object puede administrar su propio estado.
fuente
En resumen, con el patrón de estrategia podemos establecer un comportamiento sobre la marcha, con el patrón de estado, podemos estar seguros de que un objeto cambiará su comportamiento internamente con el cambio de su estado.
fuente
Cuando tienes un proyecto que se puede dividir en 2 tareas:
tarea 1: puede usar uno de dos algoritmos diferentes para lograr: alg1, alg2
tarea 2: puede usar uno de los tres algoritmos diferentes para lograr: alg3, alg4, alg5
alg1 y alg2 son intercambiables; alg3, alg4 y alg5 son intercambiables.
Elegir qué algoritmo realizar en la tarea 1 y la tarea 2 depende de los estados:
estado 1: necesita alg1 en la tarea 1 y alg3 en la tarea 2
estado 2: necesita alg2 en la tarea 1 y alg5 en la tarea 2
Su contexto puede cambiar el objeto de estado del estado 1 al estado 2. Luego, su tarea sería realizada por alg2 y alg5, en lugar de alg1 y alg3.
Puede agregar más algoritmos intercambiables para la tarea 1 o la tarea 2. Este es el patrón de estrategia.
Puede tener más estados con diferentes combinaciones de algoritmos en la tarea 1 y la tarea 2. El patrón de estado le permite cambiar de un estado a otro y realizar diferentes combinaciones de algoritmos.
fuente
'Estrategia' es solo un algoritmo que puede cambiarlo en diferentes circunstancias según su necesidad, y procesa algo por usted. Ex. Puedes elegir cómo comprimir un archivo. zip o rar ... en un método.
Pero 'Estado' PUEDE cambiar todo el comportamiento de su objeto, cuando cambia, incluso puede cambiar otros campos ... es por eso que tiene una referencia a su propietario. Debería notar que cambiar un campo de objeto puede cambiar el comportamiento del objeto. Ex. cuando cambia State0 a State1 en obj, cambia un número entero a 10 .. así que cuando llamamos a obj.f0 () que hace algunos cálculos y usa ese número entero, afecta el resultado.
fuente