Patrón de comando

Al igual que  los artículos anteriores  , analicemos un problema de diseño para comprender el patrón de comando. Supongamos que está construyendo un sistema de automatización del hogar. Hay un control remoto programable que se puede usar para encender y apagar varios elementos en su hogar, como luces, estéreo, aire acondicionado, etc. Se parece a esto.

  Puede hacerlo con declaraciones if-else simples como

if (buttonPressed == button1)
     lights.on()

Pero debemos tener en cuenta que encender algunos dispositivos como el estéreo consta de muchos pasos, como configurar cd, volumen, etc. También podemos reasignar un botón para hacer otra cosa. Al usar if-else simple, estamos codificando para la implementación en lugar de la interfaz. También hay un acoplamiento estrecho.

Entonces, lo que queremos lograr es un diseño que proporcione un acoplamiento flexible y que el control remoto no tenga mucha información sobre un dispositivo en particular. El patrón de comando nos ayuda a hacer eso.

Definición:  el patrón de comando  encapsula una solicitud como un objeto, lo que nos permite parametrizar otros objetos con diferentes requests, requests de cola o registro y admitir operaciones que se pueden deshacer.

La definición es un poco confusa al principio, pero analicemos paso a paso. En analogía con nuestro problema anterior, el control remoto es el cliente y el estéreo, las luces, etc. son los receptores. En el patrón de comando, hay un objeto de comando que encapsula una solicitud al vincular un conjunto de acciones en un receptor específico. Lo hace exponiendo solo un método de ejecución() que hace que se invoquen algunas acciones en el receptor.

Parametrizar otros objetos con diferentes requests en nuestra analogía significa que el botón que se usa para encender las luces se puede usar más tarde para encender el estéreo o tal vez para abrir la puerta del garaje.

poner en cola o registrar requests, y admitir operaciones que se pueden deshacer  significa que la operación Ejecutar del Comando puede almacenar el estado para revertir sus efectos en el Comando mismo. El comando puede tener una operación unExecute agregada que revierte los efectos de una llamada anterior para ejecutar. También puede admitir cambios de registro para que puedan volver a aplicarse en caso de un bloqueo del sistema.

A continuación se muestra la implementación de Java del ejemplo de control remoto mencionado anteriormente: 

Java

// A simple Java program to demonstrate
// implementation of Command Pattern using
// a remote control example.
 
// An interface for command
interface Command
{
    public void execute();
}
 
// Light class and its corresponding command
// classes
class Light
{
    public void on()
    {
        System.out.println("Light is on");
    }
    public void off()
    {
        System.out.println("Light is off");
    }
}
class LightOnCommand implements Command
{
    Light light;
 
    // The constructor is passed the light it
    // is going to control.
    public LightOnCommand(Light light)
    {
       this.light = light;
    }
    public void execute()
    {
       light.on();
    }
}
class LightOffCommand implements Command
{
    Light light;
    public LightOffCommand(Light light)
    {
        this.light = light;
    }
    public void execute()
    {
         light.off();
    }
}
 
// Stereo and its command classes
class Stereo
{
    public void on()
    {
        System.out.println("Stereo is on");
    }
    public void off()
    {
        System.out.println("Stereo is off");
    }
    public void setCD()
    {
        System.out.println("Stereo is set " +
                           "for CD input");
    }
    public void setDVD()
    {
        System.out.println("Stereo is set"+
                         " for DVD input");
    }
    public void setRadio()
    {
        System.out.println("Stereo is set" +
                           " for Radio");
    }
    public void setVolume(int volume)
    {
       // code to set the volume
       System.out.println("Stereo volume set"
                          + " to " + volume);
    }
}
class StereoOffCommand implements Command
{
    Stereo stereo;
    public StereoOffCommand(Stereo stereo)
    {
        this.stereo = stereo;
    }
    public void execute()
    {
       stereo.off();
    }
}
class StereoOnWithCDCommand implements Command
{
     Stereo stereo;
     public StereoOnWithCDCommand(Stereo stereo)
     {
         this.stereo = stereo;
     }
     public void execute()
     {
         stereo.on();
         stereo.setCD();
         stereo.setVolume(11);
     }
}
 
// A Simple remote control with one button
class SimpleRemoteControl
{
    Command slot;  // only one button
 
    public SimpleRemoteControl()
    {
    }
 
    public void setCommand(Command command)
    {
        // set the command the remote will
        // execute
        slot = command;
    }
 
    public void buttonWasPressed()
    {
        slot.execute();
    }
}
 
// Driver class
class RemoteControlTest
{
    public static void main(String[] args)
    {
        SimpleRemoteControl remote =
                  new SimpleRemoteControl();
        Light light = new Light();
        Stereo stereo = new Stereo();
 
        // we can change command dynamically
        remote.setCommand(new
                    LightOnCommand(light));
        remote.buttonWasPressed();
        remote.setCommand(new
                StereoOnWithCDCommand(stereo));
        remote.buttonWasPressed();
        remote.setCommand(new
                   StereoOffCommand(stereo));
        remote.buttonWasPressed();
     }
  }

Producción:

Light is on
Stereo is on
Stereo is set for CD input
Stereo volume set to 11
Stereo is off

Tenga en cuenta que el control remoto no sabe nada acerca de encender el estéreo. Esa información está contenida en un objeto de comando separado. Esto reduce el acoplamiento entre ellos. 

ventajas:

  • Hace que nuestro código sea extensible ya que podemos agregar nuevos comandos sin cambiar el código existente.
  • Reduce el acoplamiento entre el invocador y el receptor de un comando.

Desventajas:

  • Aumento en el número de clases para cada comando individual

Lectura adicional: método de comando en Python 

Referencias:

Si Este artículo es una contribución de Sulabh Kumar . te gusta GeeksforGeeks y te gustaría contribuir, también puedes escribir un artículo y enviarlo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.

Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *