112

Ambos patrones de diseño encapsulan un algoritmo y desacoplan detalles de implementación de sus clases de llamada. La única diferencia que puedo discernir es que el patrón de Estrategia toma los parámetros para la ejecución, mientras que el patrón de Comando no.Uso de un patrón de estrategia y un patrón de comando

Me parece que el patrón de comando requiere que toda la información para la ejecución esté disponible cuando se crea, y es capaz de retrasar su llamada (quizás como parte de un script).

¿Qué determinaciones guían si se utiliza un patrón u otro?

Respuesta

88

Estoy incluyendo una tabla de jerarquía de encapsulado de varios de los patrones de diseño GoF para ayudar a explicar las diferencias entre estos dos patrones. Con suerte, ilustra mejor lo que encapsula cada uno, por lo que mi explicación tiene más sentido.

En primer lugar, la jerarquía enumera el alcance para el cual un patrón dado es aplicable, o el patrón apropiado para encapsular algún nivel de detalle, dependiendo del lado de la tabla en el que comiences.

design pattern encapsulation hierarchy table

Como se puede ver en la tabla, un objeto patrón de estrategia oculta los detalles de la implementación de un algoritmo, por lo que el uso de un objeto estrategia diferente llevará a cabo la misma funcionalidad, pero de una manera diferente. Cada objeto de estrategia puede optimizarse para un factor particular u operar en algún otro parámetro; y, a través del uso de una interfaz común, el contexto puede funcionar con seguridad con cualquiera de los dos.

El patrón de comando encapsula un nivel de detalle mucho más pequeño 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 invocar los mensajes una o más veces, o pasarlos a diferentes partes del sistema o sistemas múltiples sin que se requiera conocer 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 los argumentos de objeto versus método.

+0

Entonces, si tuviera un sistema que filtrara los resultados con un "filtro de canalización" y utilizara delegados como filtros (donde cada uno de los algoritmos del filtro estaría encapsulado dentro de una función) ¿se consideraría un patrón de comando? En este caso, veo que el delegado de la función de filtro proporciona un tipo de contrato para lo que cada filtro debe cumplir en términos de entrada y salida. – KTF

+3

@KTF, no. El patrón de comando emplea un objeto que tiene la mayoría (si no toda) la información necesaria (p. Ej., Receptor, selector, argumentos) para invocar el método de un objeto. Es un patrón simplista que se puede utilizar en otros patrones de diseño, como Chain of Responsibility, Collection y el patrón Pipeline que describes. El "contrato de tipo" provisto por sus delegados es otro patrón, Interface. – Huperniketes

15

La forma en que lo veo es que tiene múltiples formas de hacer lo mismo, cada una de ellas es una estrategia, y algo en tiempo de ejecución determina qué estrategia se ejecuta.

Quizás primer intento StrategyOne, si los resultados no son lo suficientemente buenos, trate StrategyTwo ...

comandos están obligados a cosas distintas que deben pasar como TryToWalkAcrossTheRoomCommand. Este comando se disparará cada vez que algún objeto intente cruzar la habitación, pero dentro de él podría intentar con StrategyOne y StrategyTwo intentar cruzar la habitación.

Marcos

+2

RE: "múltiples formas de hacer lo mismo" - Eso parece estar en conflicto con algunos de los ejemplos comunes de Estrategia. Específicamente aquellos en los que hay clases de implementación que hacen suma, resta, multiplicación, etc. ¿Quizás esos no son buenos ejemplos? –

+1

@JoshuaDavis todas estas "suscripciones" son casos especiales de una estrategia: * operación aritmética *. tienen argumentos comunes (2 operandos) y producen un valor como resultado. más o menos haciendo lo mismo (siendo blackboxes) a su manera, dependiendo de la implementación. así que no veo conflicto aquí, sino todo lo contrario: buen ejemplo =) –

48

Estrategias encapsulan algoritmos. Los comandos separan al emisor del receptor de una solicitud, convierten una solicitud en un objeto.

Si se trata de un algoritmo, cómo se hará algo, utilice 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 se ponen en cola los mensajes para su uso posterior, como una tarea o una transacción.

+0

que tenía sentido http://en.wikipedia.org/wiki/Command_Pattern cliente e invocador están atados, pero al mismo tiempo, no saben sobre ¡El uno al otro! –

7

En mi opinión, podría estar equivocado, pero trato el command como función para ejecutar o como 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 para el patrón de comando:

  • Todos los botones en la barra de herramientas de la aplicación están asociados con alguna acción.
  • El botón es el ejecutor en este caso.
  • La acción es el comando en este caso.

La orden se suele limitada a un cierto margen o zona de negocios, pero no es necesario: es posible que tenga comandos que emiten una factura, iniciar un cohete o eliminar un archivo de la aplicación de la misma interfaz (por ejemplo, solo execute() método) dentro de una solicitud. A menudo, los comandos son autónomos, por lo que no necesitan nada del ejecutor para procesar la tarea que se proponen (toda la información necesaria se proporciona en tiempo de construcción), a veces los comandos son sensibles al contexto y deberían ser capaces de descubrir este contexto. (Backspace El comando debe saber la posición de intercalación en el texto para eliminar correctamente el carácter anterior; El comando Deshacer debe descubrir la transacción actual para deshacer; ...).

El strategy es un poco diferente: está más ligado a alguna área. La estrategia puede definir una regla para formatear una fecha (en UTC? ¿Específico de la configuración regional?) (Estrategia "formateador de fechas") o para calcular un cuadrado para una figura geométrica (estrategia de "calculadora cuadrada"). Las estrategias son, en este sentido, objetos de peso mosca, que toman algo como entrada ("fecha", "figura", ...) y toman una decisión sobre la base.Tal vez no sea el mejor, pero un buen ejemplo de estrategia es uno conectado con la interfaz javax.xml.transform.Source: dependiendo de si el objeto pasado es DOMSource o SAXSource o la estrategia (= transformador XSLT en este caso) aplicará diferentes reglas para procesarla. La implementación puede ser simple switch o involucrar Chain of responsibility pattern.

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.

+1

* Trato el comando como una función de devolución de llamada, o reacción. Debe haber al menos dos jugadores: uno que solicita la acción y el otro que ejecuta ... * - Entiendo lo que intentas decir, pero evitaría utilizar la palabra "devolución de llamada", porque a menudo el La palabra "devolución de llamada" implica una invocación asíncrona y no es necesario realizar invocaciones asincrónicas para que el patrón de comando sea útil. Caso en cuestión: Microsoft Word.Los clic de botón de la barra de herramientas y las teclas de método abreviado no invocan comandos asíncronos, pero podemos apreciar cómo sería útil el patrón de comando en este caso –

+0

Acepto, aunque como dijo Jim, editaría para eliminar la referencia a la devolución de llamada. – JamesC

+0

Gracias, he hecho algunas extensiones. Avísame si estás de acuerdo/en desacuerdo. –

22

Respondiendo a una pregunta muy antigua. (¿Alguien está viendo las últimas respuestas en lugar de las más votadas?)

Es una confusión válida debido a las similitudes. Los patrones de Estrategia y Comando utilizan la encapsulación . Pero eso no los hace iguales.

La diferencia clave es comprender que se encapsula. El principio OO, ambos patrones dependen de, es Encapsula lo que varía.

En caso de estrategia, lo que varía es algoritmo. Por ejemplo, un objeto de estrategia sabe cómo exportar a un archivo XML, mientras que el otro lo envía a, por ejemplo, JSON. Se mantienen diferentes algoritmos (encapsulado) en diferentes clases. Es tan simple como eso.

En caso de comando, lo que varía es solicitud sí mismo. La solicitud puede venir de File Menu > Delete o Right Click > Context Menu > Delete o Just 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. Como las solicitudes ahora son un montón de objetos, podríamos gestionarlas fácilmente. De repente, se vuelve trivial proporcionar funcionalidades como deshacer o rehacer.

No importa cómo el comando implementa la lógica solicitada. Al ejecutar execute(), puede implementar un algoritmo para activar la eliminación o incluso puede delegarlo a otros objetos, incluso puede delegar en una estrategia. Es solo el detalle de implementación del patrón de comando. Es por esto que se denomina como comando pesar de que no es una forma educada de solicitud: -)

contraste con la estrategia; este patrón solo se refiere a 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 clase.

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.

3

de comando:

componentes básicos:

  1. Comando declara una interfaz de comandos abstractos como execute()
  2. receptor sabe cómo ejecutar un comando en particular
  3. invocador sostiene ConcreteCommand, que tiene que ser ejecutado
  4. cliente crea ConcreteCommand y asignar receptor
  5. ConcreteCommand define vinculante entre Co mmand y receptor

flujo de trabajo:

cliente llama invocador =>invocador llama ConcreteCommand =>ConcreteCommand llamadas receptor método, que implementa abstracta Comando método.

Ventaja: El cliente no se ve afectado por los cambios en Comando y Receptor. Invoker proporciona un acoplamiento flexible entre el Cliente y el Receptor. Puede ejecutar múltiples comandos con el mismo Invoker.

Comando patrón le permite ejecutar un comando en diferentes receptores utilizando misma invocador. Invocador no es consciente de tipo de receptor

Para una mejor comprensión de los conceptos, echar un vistazo a este JournalDev article por Pankaj Kumar y DZone article por James Sugrue además de enlace de Wikipedia.

Puede utilizar Comando patrón para

  1. desacoplar el invocador & receptor de mando

  2. Implementar mecanismo de devolución de llamada

  3. Implementar deshacer y rehacer funcionalidad

  4. mantener un historial de los comandos

java.lang.Thread es una buena ejecución de comandos patrón. Usted puede tratar de rosca como invocador & clase que implementa Ejecutable como ConcreteCommonad/receptor y run() método Comando.

versión de deshacer/rehacer del patrón de comando se puede leer en Estrategiaarticle

de Theodore Norvell:

patrón de estrategia es muy sencillo de entender. Use este patrón cuando

Tiene múltiples implementaciones para un algoritmo y la implementación del algoritmo puede cambiar en tiempo de ejecución según las condiciones particulares.

tomar un ejemplo del componente de tarifa del sistema de reservas de la aerolínea

Airlines que les gustaría ofrecer tarifas diferentes durante diferentes períodos de tiempo - Pico y meses de menor demanda. Durante los días pico de viaje, le gustaría estimular la demanda ofreciendo atractivos descuentos.

comida para llevar clave de Estrategia patrón:

  1. Es un patrón de comportamiento
  2. Se basa en la delegación
  3. Cambia tripas del objeto mediante la modificación de la conducta método
  4. Se utiliza para cambiar entre familia de algoritmos
  5. Cambia el comportamiento del objeto en el tiempo de ejecución

Puestos relacionados con ejemplos de código:

Using Command Design pattern

Real World Example of the Strategy Pattern

0

Para mí, la diferencia es uno de intenciones. Las implementaciones de ambos modelos son muy similares, pero tienen diferentes propósitos:

  • para una estrategia, el componente mediante el objeto sabe lo hace el objeto (y lo utilizará para realizar una parte de su propio trabajo), pero no le importa cómo lo hace.

  • para un comando, el componente mediante el objeto no conoce ni lo que hace el comando ni cómo lo hace - que sólo sabe cómo invocar la misma. La tarea del que llama es simplemente ejecutar el comando: el procesamiento llevado a cabo por el comando no forma parte del trabajo principal del llamador.

Esta es la diferencia: ¿el objeto que utiliza el componente realmente sabe o le importa 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 el valor devuelto, probablemente sea un Comando (tenga en cuenta que algo así 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 restituye). a lo que originalmente suministró el Comando).

Cuestiones relacionadas