Incluyo una tabla de jerarquía de encapsulación de varios de los patrones de diseño de GoF para ayudar a explicar las diferencias entre estos dos patrones. Con suerte, ilustra mejor lo que encapsula cada uno para que mi explicación tenga más sentido.
En primer lugar, la jerarquía enumera el alcance para el que se aplica un patrón determinado, o el patrón apropiado a utilizar para encapsular algún nivel de detalle, según el lado de la tabla en el que comience.
Como puede ver en la tabla, un objeto de Patrón de estrategia oculta los detalles de la implementación de un algoritmo, por lo que el uso de un objeto de estrategia diferente realizará la misma funcionalidad pero de una manera diferente. Cada objeto de estrategia puede optimizarse para un factor particular u operar sobre algún otro parámetro; y, mediante el uso de una interfaz común, el contexto puede funcionar de forma segura con cualquiera de ellos.
El patrón de comando encapsula un nivel de detalle mucho menor que un algoritmo. Codifica los detalles necesarios para enviar un mensaje a un objeto: receptor, selector y argumentos. El beneficio de objetivar una parte tan pequeña de la ejecución del proceso es que dichos mensajes se pueden invocar a lo largo de diferentes puntos de tiempo o ubicación de una manera general sin tener que codificar sus detalles. Permite que los mensajes se invoquen una o más veces, o que se pasen a diferentes partes del sistema o múltiples sistemas sin requerir que se conozcan los detalles de una invocación específica antes de la ejecución.
Como es típico para los patrones de diseño, no requieren que todas las implementaciones sean idénticas en detalle para llevar el nombre del patrón. Los detalles pueden variar en la implementación y en qué datos se codifican en el objeto en comparación con los argumentos del método.
Las estrategias encapsulan algoritmos. Los comandos separan al remitente del receptor de una solicitud, convierten una solicitud en un objeto.
Si es un algoritmo, cómo se hará algo, use una estrategia. Si necesita separar la llamada de un método de su ejecución, use un comando. Los comandos se utilizan a menudo cuando pone en cola mensajes para su uso posterior, como una tarea o una transacción.
fuente
Respondiendo a una pregunta muy antigua. (¿Alguien ve las últimas respuestas en lugar de las más votadas?)
Es una confusión válida debido a las similitudes. Tanto los patrones de estrategia como los de comando utilizan encapsulación . Pero eso no los hace iguales.
La diferencia clave es comprender qué está encapsulado. El principio de OO, del que dependen ambos patrones, es Encapsular lo que varía .
En caso de estrategia, lo que varía es el algoritmo . Por ejemplo, un objeto de estrategia sabe cómo exportar a un archivo XML, mientras que el otro lo hace, digamos, JSON. Los diferentes algoritmos se mantienen ( encapsulados ) en diferentes clases. Es tan simple como eso.
En caso de comando, lo que varía es la propia solicitud . La solicitud puede provenir de
File Menu > Delete
oRight Click > Context Menu > Delete
oJust Delete Button pressed
. Los tres casos pueden generar 3 objetos de comando del mismo tipo. Estos objetos de comando solo representan 3 solicitudes de eliminación; no algoritmo de eliminación. Dado que las solicitudes ahora son un montón de objetos, podríamos administrarlas fácilmente. De repente, se vuelve trivial proporcionar funciones como deshacer o rehacer.No importa cómo el comando implemente la lógica solicitada. Al llamar a execute (), puede implementar un algoritmo para activar la eliminación o incluso puede delegarlo a otros objetos, incluso puede delegarlo en una estrategia. Es solo un detalle de implementación del patrón de comando. Es por eso que se nombra como comando, aunque no es una forma educada de solicitar : -)
Compárelo con la estrategia; este patrón solo se ocupa de la lógica real que se ejecuta. Si hacemos eso, ayuda a lograr diferentes combinaciones de comportamientos con un conjunto mínimo de clases, evitando así la explosión de clases.
Creo que Command nos ayuda a ampliar nuestra comprensión de la encapsulación, mientras que Strategy proporciona un uso natural de la encapsulación y el polimorfismo.
fuente
La forma en que lo veo es que tiene varias formas de hacer lo mismo, cada una de ellas es una estrategia, y algo en tiempo de ejecución determina qué estrategia se ejecuta.
Tal vez primero pruebe StrategyOne, si los resultados no son lo suficientemente buenos, prueba StrategyTwo ...
Los comandos están vinculados a distintas cosas que deben suceder, como TryToWalkAcrossTheRoomCommand. Este comando se activará siempre que algún objeto intente cruzar la habitación, pero dentro de él, podría probar StrategyOne y StrategyTwo para intentar cruzar la habitación.
marca
fuente
Puede que me equivoque en mi opinión, pero trato el comando como una función a ejecutar o una reacción. Debe haber al menos dos jugadores: el que solicita la acción y el que ejecuta la acción. La GUI es un ejemplo típico de patrón de comando:
El comando generalmente está limitado a algún ámbito o área comercial, pero no es necesario: puede tener comandos que emitan una factura, inicien un cohete o eliminen un archivo implementando la misma interfaz (por ejemplo,
execute()
método único ) dentro de una aplicación. A menudo, los comandos son autocontenidos, por lo que no necesitan nada del ejecutor para procesar la tarea que pretenden realizar (toda la información necesaria se proporciona en el momento de la construcción), a veces los comandos son sensibles al contexto y deberían poder descubrir este contexto ( Retroceso de comandos debe conocer la posición de intercalación en el texto para eliminar correctamente el carácter anterior; rollback comando debe descubrir la transacción actual de reversión; ...).La estrategia es un poco diferente: está más ligada a un área. La estrategia puede definir una regla para formatear una fecha (¿en UTC? ¿Específico de la localidad?) (Estrategia de "formateador de fechas") o para calcular un cuadrado para una figura geométrica (estrategia de "calculadora de cuadrados"). Las estrategias son en este sentido objetos de peso mosca, que toman algo como entrada ("fecha", "figura", ...) y toman alguna decisión en base a ello. Quizás no sea el mejor, pero buen ejemplo de estrategia es uno conectado con
javax.xml.transform.Source
la interfaz: dependiendo de si el objeto pasado esDOMSource
oSAXSource
oStreamSource
la estrategia (= XSLT transformador en este caso) se aplicarán diferentes reglas para procesarlo. La implementación puede ser simpleswitch
o involucrar un patrón de Cadena de responsabilidad .Pero, de hecho, hay algo en común entre estos dos patrones: los comandos y las estrategias encapsulan algoritmos dentro de la misma área semántica.
fuente
Mando:
Componentes básicos:
execute()
Flujo de trabajo:
El cliente llama a Invoker => El invocador llama a ConcreteCommand => ConcreteCommand llama al método Receiver , que implementa el método de comando abstracto .
Ventaja : el cliente no se ve afectado por los cambios en Command y Receiver. El invocador proporciona un acoplamiento flexible entre el cliente y el receptor. Puede ejecutar varios comandos con el mismo invocador.
El patrón de comando le permite ejecutar un comando en diferentes receptores usando el mismo invocador . El invocador desconoce el tipo de receptor
Para una mejor comprensión de los conceptos, eche un vistazo a este artículo de JournalDev de Pankaj Kumar y al artículo de dzone de James Sugrue, además del enlace de Wikipedia.
Puede utilizar el patrón Command para
Desacoplar al invocador y al receptor del mando
Implementar mecanismo de devolución de llamada
Implementar la funcionalidad de deshacer y rehacer
Mantener un historial de comandos
java.lang.Thread
es una buena implementación del patrón Command . Puede tratar Thread como invocador y clase implementando Runnable como ConcreteCommonad / Receiver y elrun()
método como Command .La versión Deshacer / Rehacer del patrón de comando se puede leer en el artículo de Theodore Norvell
Estrategia:
El patrón de estrategia es muy simple de entender. Utilice este patrón cuando
Tiene varias implementaciones para un algoritmo y la implementación del algoritmo puede cambiar en el tiempo de ejecución según las condiciones particulares .
Tome un ejemplo del componente de tarifa del sistema de reserva de aerolíneas
A las aerolíneas les gustaría ofrecer diferentes tarifas durante diferentes períodos de tiempo: meses pico y no pico. Durante los días de menor actividad turística, le gustaría estimular la demanda ofreciendo atractivos descuentos.
Conclusiones clave del patrón de estrategia :
Publicaciones relacionadas con ejemplos de código:
Usando el patrón Command Design
Ejemplo del mundo real del patrón de estrategia
fuente
Para mí, la diferencia es de intención. Las implementaciones de ambos patrones son bastante similares, pero tienen diferentes propósitos:
Para una estrategia, el componente que usa el objeto sabe lo que hace el objeto (y lo usará para realizar una parte de su propio trabajo), pero no le importa cómo lo hace.
Para un comando, el componente que usa el objeto no sabe lo que hace el comando ni cómo lo hace, solo sabe cómo invocarlo. La tarea de la persona que llama es simplemente ejecutar el comando; el procesamiento realizado por el comando no forma parte del trabajo principal de la persona que llama.
Esta es la diferencia: ¿el objeto que usa el componente realmente sabe o se preocupa por lo que hace el componente? La mayoría de las veces, esto se puede determinar en función de si el objeto patrón devuelve un valor a su invocador. Si el invocador se preocupa por lo que hace el objeto patrón, probablemente querrá que devuelva algo y será una estrategia. Si no le importa ningún valor de retorno, probablemente sea un comando (nota, algo como un Java Callable sigue siendo un comando porque, aunque devuelve un valor, a la persona que llama no le importa el valor, simplemente lo devuelve a lo que originalmente suministró el comando).
fuente