studio reales proyectos programacion libro introducción incluye herramientas fundamentos fuente español código con avanzado aplicaciones java oop design-patterns design command-pattern

java - reales - libro de android studio en español pdf



¿Por qué debería usar el patrón de diseño de comando mientras puedo llamar fácilmente a los métodos requeridos? (8)

Centrémonos en el aspecto de no implementación del diseño del comando y algunas razones principales para usar el patrón de diseño de comando agrupado en dos categorías principales:

  • Ocultar la implementación real de cómo se ejecuta el comando
  • Permita que los métodos se construyan alrededor del comando, también conocido como extensiones de comando

Ocultar implementación

En la mayoría de los programas, querrá ocultar la implementación para que, al observar el problema más importante, consista en un subconjunto comprensible de comandos / código. Es decir, no necesita / desea saber los detalles sangrientos de cómo se enciende una luz o se inicia un automóvil. Si tu objetivo es hacer que el auto arranque, no necesitas entender cómo funciona el motor y cómo necesita combustible para entrar en el motor, cómo funcionan las válvulas, ...

Indicando la acción, no cómo se hace

Un comando te da este tipo de vista. Entenderá inmediatamente lo que hace el comando TurnLightOn , o StartCar . Usando un comando, ocultará los detalles de cómo se hace algo, mientras indica claramente la acción que se va a ejecutar.

Permitir el cambio de detalles internos

Además, digamos que más adelante reconstruir toda su clase de Light , o una clase de Car , que requiere la instancia de varios objetos diferentes, y posiblemente necesite algo más antes de realizar su operación deseada. En este caso, si ha implementado el método de acceso directo, en muchos lugares, deberá cambiarlo en todos los lugares donde lo haya codificado de antemano. Usando un comando, puede cambiar los detalles internos de cómo hacer cosas sin cambiar la llamada del comando.

Posibles extensiones de comando

El uso de una interfaz de comando le proporciona una capa adicional entre el código que utiliza el comando y el código que realiza la acción real del comando. Esto puede permitir múltiples buenos escenarios.

Extensión de seguridad o exposición de interfaz

Usando una interfaz de comando, también puede limitar el acceso a sus objetos, lo que le permite definir otro nivel de seguridad. Podría tener sentido tener un módulo / biblioteca con un acceso bastante abierto para que pueda manejar casos especiales internos fácilmente.

Desde el exterior, sin embargo, es posible que desee restringir el acceso a la luz para que solo se active o desactive. El uso de comandos le da la capacidad de limitar la interfaz hacia una clase .

Además, si lo desea, puede crear un sistema de acceso de usuario dedicado alrededor de los comandos. Esto dejaría toda su lógica comercial abierta y accesible y sin restricciones, pero aún podría restringir fácilmente el acceso a nivel de comando para hacer cumplir el acceso adecuado.

Interfaz común para ejecutar cosas

Al construir un sistema grande y suficiente, los comandos brindan una manera ordenada de puentear entre diferentes módulos / bibliotecas. En lugar de que necesite examinar cada detalle de implementación de una clase dada, puede ver qué comandos están accediendo a la clase.

Y como está omitiendo los detalles de implementación en el comando mismo, puede usar un método común para crear una instancia del comando, ejecutarlo y revisar el resultado. Esto permite una codificación más fácil, en lugar de tener que leer sobre cómo crear una instancia de esa clase particular de Light o Car , y determinar el resultado de la misma.

Secuencia de comandos

Usando comandos, también puedes hacer cosas como la secuencia de comandos. Esto es porque realmente no importa si está ejecutando el TurnOnLight o StartCar , puede ejecutar secuencias de tesis ya que se ejecutan de la misma manera. Lo que a su vez puede permitir que se ejecuten cadenas de comandos, lo que podría ser útil en situaciones múltiples.

Puedes construir macros, ejecutar conjuntos de comandos que creas que están agrupados. Es decir, la secuencia de comandos: UnlockDoor , EnterHouse , TurnOnLight . Una secuencia natural de comandos, pero no es probable que se convierta en un método, ya que utiliza diferentes objetos y acciones.

Serialización de comandos

Los comandos son bastante pequeños por naturaleza y también permiten la serialización bastante bien. Esto es útil en el contexto de servidor-cliente o contexto de servicio de microservicio de programa.

El servidor (o programa) podría desencadenar un comando, que luego serializa el comando, lo envía a través de algún protocolo de comunicación (es decir, cola de eventos, cola de mensajes, http, ...) a alguien que realmente maneja el comando. No es necesario primero crear una instancia del objeto en el servidor, es decir, una Light que podría ser ligera (juego de palabras), o un Car que podría ser una estructura realmente grande. Solo necesitas el comando y posiblemente algunos parámetros.

Este podría ser un buen lugar para presentar el patrón de separación de responsabilidad de consulta de comandos de CQRS para más estudios.

Seguimiento de comandos

Usar la capa adicional de comandos en su sistema también podría permitir el registro o seguimiento de comandos, si es una necesidad comercial. En lugar de hacer esto por todos lados, puede recopilar seguimiento / registro dentro del módulo de comando.

Esto permite cambios sencillos del sistema de registro, o la adición de cosas como el tiempo, o habilitar / deshabilitar el registro. Y todo se mantiene fácilmente dentro del módulo de comando.

El seguimiento de comandos también permite acciones de deshacer, ya que puede elegir repetir los comandos desde un estado determinado. Necesita un poco de configuración extra, pero es bastante factible.

En resumen, los comandos pueden ser realmente útiles ya que permiten la conexión entre las diferentes partes de su programa que pronto será grande, ya que son livianos y fáciles de recordar / documentar y ocultan los detalles de implementación cuando es necesario. Además, los comandos permiten varias extensiones útiles, que al construir un sistema más grande serán útiles: es decir, interfaz común, secuenciación, serialización, seguimiento, registro, seguridad.

Estoy estudiando el patrón de diseño del comando , y estoy bastante confundido con la forma de usarlo. El ejemplo que tengo está relacionado con una clase de control remoto que se usa para encender y apagar las luces.

¿Por qué no debería usar los métodos switchOn () / switchOff () de la clase Light en lugar de tener clases y métodos separados que eventualmente llaman a los métodos switchOn / switchOff?

Sé que mi ejemplo es bastante simple , pero ese es el punto. No pude encontrar ningún problema complejo en Internet para ver el uso exacto del patrón de diseño del comando.

Si conoce algún problema complejo del mundo real que haya resuelto y que pueda resolverse utilizando este patrón de diseño, compártalo conmigo. Nos ayuda a mí y a los futuros lectores de esta publicación a comprender mejor el uso de este patrón de diseño. Gracias

//Command public interface Command { public void execute(); } //Concrete Command public class LightOnCommand implements Command { //Reference to the light Light light; public LightOnCommand(Light light) { this.light = light; } public void execute() { light.switchOn(); //Explicit call of selected class''s method } } //Concrete Command public class LightOffCommand implements Command { //Reference to the light Light light; public LightOffCommand(Light light) { this.light = light; } public void execute() { light.switchOff(); } } //Receiver public class Light { private boolean on; public void switchOn() { on = true; } public void switchOff() { on = false; } } //Invoker public class RemoteControl { private Command command; public void setCommand(Command command) { this.command = command; } public void pressButton() { command.execute(); } } //Client public class Client { public static void main(String[] args) { RemoteControl control = new RemoteControl(); Light light = new Light(); Command lightsOn = new LightsOnCommand(light); Command lightsOff = new LightsOffCommand(light); //Switch on control.setCommand(lightsOn); control.pressButton(); //Switch off control.setCommand(lightsOff); control.pressButton(); } }

¿Por qué no debería usar código fácilmente como el siguiente?

Light light = new Light(); switch(light.command) { case 1: light.switchOn(); break; case 2: light.switchOff(); break; }


El ejemplo ICommand usted brinda es bastante limitado y solo es de uso real en un lenguaje de programación que no tiene expresiones lambda. Sprinter lo cubre muy bien en sus respuestas que muestran el uso de fábricas de comandos.

La mayoría de los casos del patrón de comando incluyen otros métodos, por ejemplo, CanRun y / o Undo . Esto permite que un botón actualice su estado de activación en función del estado del comando, o una aplicación para implementar una pila de deshacer.

Al igual que la mayoría de los patrones de diseño, el Patrón de Comando se vuelve propio cuando las cosas se vuelven un poco más complejas. También es bien sabido, por lo que ayuda a que su código sea claramente para la mayoría de los programadores.


Hay un par de beneficios del patrón Command que he experimentado. Pero antes que nada, me gustaría recordar que, como todos los demás patrones, este patrón también es para aumentar la legibilidad del código y aportar una comprensión común a su (probablemente) base de código compartido.

Uso este patrón para pasar de una interfaz orientada a métodos a una interfaz orientada a comandos. Eso significa que estoy encapsulando llamadas de método en comandos concretos junto con los datos necesarios. Hace que el código sea más legible, sí, pero lo más importante es que puedo tratar los métodos como objetos, lo que te permite agregar / eliminar / modificar comandos fácilmente sin aumentar la complejidad del código. Por lo tanto, facilita la administración y la facilidad de lectura.

En segundo lugar, como tiene sus métodos como objetos, puede almacenarlos / ponerlos en cola para ejecutarlos más tarde. O para cancelarlos incluso después de haberlos ejecutado. Aquí es donde este patrón te ayuda a implementar "Deshacer".

Finalmente, el patrón de comando también se usa para desacoplar la ejecución del comando y los comandos mismos. Es como si un camarero no supiera cómo cocinar los pedidos que recibió. A él no le importa Él no tiene que saber. Si él lo supiera, estaría trabajando como cocinero también. Y si el dueño del restaurante quiere despedir al camarero, termina sin tener cocinero. Por supuesto, esta definición no es especial o está relacionada solo con el patrón de comando. Eso explica por qué necesitamos el desacoplamiento o la administración de dependencias en general.


La principal motivación para usar el patrón Command es que el ejecutor del comando no necesita saber nada sobre qué comando es, qué información de contexto necesita o qué hace. Todo eso está encapsulado en el comando.

Esto le permite hacer cosas tales como tener una lista de comandos que se ejecutan en orden, que dependen de otros elementos, que están asignados a algún evento desencadenante, etc.

En su ejemplo, podría tener otras clases (p. Ej Air Conditioner ) que tengan sus propios comandos (por ejemplo, Turn Thermostat Up , Turn Thermostat Down ). Cualquiera de estos comandos podría asignarse a un botón o activarse cuando se cumple alguna condición sin que sea necesario conocer el comando.

Entonces, en resumen, el patrón encapsula todo lo requerido para tomar una acción y permite que la ejecución de la acción ocurra completamente independientemente de ese contexto. Si eso no es un requisito para usted, entonces el patrón probablemente no sea útil para su espacio problemático.

Aquí hay un caso de uso simple:

interface Command { void execute(); } class Light { public Command turnOn(); public Command turnOff(); } class AirConditioner { public Command setThermostat(Temperature temperature); } class Button { public Button(String text, Command onPush); } class Scheduler { public void addScheduledCommand(Time timeToExecute, Command command); }

Entonces puedes hacer cosas como:

new Button("Turn on light", light.turnOn()); scheduler.addScheduledCommand(new Time("15:12:07"), airCon.setThermostat(27)); scheduler.addScheduledCommand(new Time("15:13:02"), light.turnOff());

Como puede ver, el Button y el Scheduler no necesitan saber nada sobre los comandos. Scheduler es un ejemplo de una clase que podría contener una colección de comandos.

Tenga en cuenta también que en Java 8 las interfaces funcionales y las referencias de métodos han hecho que este tipo de código sea aún más nítido:

@FunctionalInterface interface Command { void execute(); } public Light { public void turnOn(); } new Button("Turn On Light", light::turnOn);

Ahora los métodos que se convierten en comandos ni siquiera necesitan saber acerca de los comandos: siempre que tengan la firma correcta, pueden crear silenciosamente un objeto de comando anónimo haciendo referencia al método.


Las posibilidades son muchas, pero típicamente sería algo así como:

  • construir un marco de línea de comandos que abstraiga el análisis de las opciones de la acción. Luego puede registrar una acción con algo como opts.register("--on", new LightOnCommand()) .
  • permitiendo a los usuarios arrastrar y soltar una secuencia de acciones para ejecutarlas como una macro
  • registrar una devolución de llamada cuando se desencadena algún evento, como on(Event.ENTER_ROOM, new LightOnCommand())

El patrón general aquí es que tiene una parte del código responsable de descubrir que se deben tomar algunas medidas sin saber qué acción es esa, y otra parte del código sabe cómo hacer una acción pero no cuándo hacerlo eso.

Por ejemplo, en ese primer ejemplo, la instancia de opts sabe que cuando ve una opción de línea de comando --on, debería encender las luces. Pero lo sabe sin saber realmente qué significa "encender las luces". De hecho, bien podría ser que la instancia de opts provenga de una biblioteca de terceros, por lo que no puede saber acerca de las luces. Todo lo que sabe es cómo evaluar las acciones (comandos) con las opciones de línea de comandos que analiza.


Los patrones de diseño se desarrollan básicamente para resolver problemas complejos o, en otras palabras, podemos decir que se utilizan para evitar que su solución se vuelva compleja. Nos brindan la flexibilidad de agregar nuevas funcionalidades en el futuro sin hacer muchos cambios en nuestro código existente. Abierto para extensión, cerrado para modificación.

Command Pattern básicamente encapsula una solicitud como un objeto y, por lo tanto, le permite parametrizar otros objetos con diferentes solicitudes y operaciones de soporte para deshacer.

Cuando vemos un control remoto que es un mejor ejemplo de patrón de comando. En este caso, hemos asociado un comando concreto a cada botón y ese comando tiene una información del receptor sobre la cual actuar.

En el ejemplo de la caja del interruptor, suponga que si desea asociar un botón del control remoto al ventilador en lugar de a la luz, deberá cambiar el código existente porque necesita asociar un botón con un comando. Esta es la esencia del patrón de comando, ya que le proporciona la flexibilidad de asociar cualquier comando con un botón para que, en tiempo de ejecución, pueda cambiar la funcionalidad. Aunque, en general, el control remoto de TV no tiene esta viabilidad, es decir, no puede hacer que el botón de subir volumen funcione al bajar el volumen. Pero si usa cualquier aplicación para controlar su TV, puede asignar cualquier botón al comando disponible.

Además, al usar el patrón de comando, puede tener un conjunto de comandos para que una funcionalidad determinada lo logre, es decir, un comando de macro. Por lo tanto, si piensa en un nivel más amplio, este patrón puede darle la flexibilidad para extender las funcionalidades.

El patrón de comando nos ayuda a desacoplar el invocador (control remoto) y el receptor (luz, ventilador, etc.) con la ayuda del objeto de comando (LightOnCommand, FanOffCommand, etc.).


No es necesario. Los patrones de diseño son simplemente pautas que algunas personas en el pasado han encontrado útiles al escribir aplicaciones de complejidad significativa.

En su caso, si lo que tiene que hacer es encender y apagar la luz y no mucho más, la segunda opción es obvia.

Menos código es casi siempre mejor que más código.


Puedes hacer lo que creas, pero es bueno seguir el patrón de usability de la usability de manageability del código.

En el ejemplo de la vida real, Light sería una interfaz. Tienes diferentes implementaciones de Light como LEDLight , TubeLight

Si ejecuta el comando concreto a través de Inovker ( RemoteControl ), no necesita preocuparse por los cambios en el nombre del método en Receiver . switchOn() in Light can be changed to switchOnDevice() in future . Pero no afecta a Invoker ya que ConcreteCommand ( LightsOnCommand ) hará cambios relevantes.

Asuma el escenario, donde publica sus interfaces para un servicio (Servicio A) y la implementación en otros servicios (Servicio B).

Ahora el Servicio A no debe saber acerca de los cambios en el Receiver .

Invoker proporciona un acoplamiento flexible entre el remitente y el destinatario del mensaje.

Eche un vistazo a algunas preguntas SE más relacionadas:

Uso del patrón de diseño de comando

Command Pattern parece innecesariamente complejo (¿qué estoy deficiente en entender?)