Menu
Coddy logo textTech

Padrão Command

Parte da seção Programação Orientada a Objetos do Journey de Java da Coddy. Lição 70 de 87.

O padrão Command é um padrão comportamental de projeto que transforma uma solicitação em um objeto independente contendo todas as informações sobre a solicitação. Essa transformação permite passar solicitações como argumentos de métodos, adiar ou enfileirar a execução de uma solicitação e oferecer suporte a operações que podem ser desfeitas.

Pense nisso como um restaurante: em vez de dizer diretamente ao chef o que cozinhar, você escreve seu pedido em um papel. O garçom (invocador) leva o papel (comando) até a cozinha, onde ele pode ser colocado em uma fila, priorizado ou até mesmo cancelado. O padrão desacopla o objeto que invoca a operação daquele que a executa.

O padrão tem quatro componentes principais: uma interface Command que declara o método execute, classes ConcreteCommand que implementam ações específicas, um Receiver que realiza o trabalho de fato e um Invoker que aciona os comandos:

interface Command {
    void execute();
}
class Light {  // Receptor
    public void turnOn() {
        System.out.println("Light is ON");
    }
    public void turnOff() {
        System.out.println("Light is OFF");
    }
}
class LightOnCommand implements Command {
    private Light light;
    
    public LightOnCommand(Light light) {
        this.light = light;
    }
    
    public void execute() {
        light.turnOn();
    }
}
class RemoteControl {  // Invocador
    private Command command;
    
    public void setCommand(Command command) {
        this.command = command;
    }
    
    public void pressButton() {
        command.execute();
    }
}

O invocador não sabe qual ação será realizada. Ele apenas chama execute():

Light light = new Light();
Command lightOn = new LightOnCommand(light);

RemoteControl remote = new RemoteControl();
remote.setCommand(lightOn);
remote.pressButton();  // Saída: Light is ON

O Padrão de Comando é excelente quando você precisa enfileirar operações, implementar funcionalidades de desfazer/refazer ou agendar tarefas para execução posterior. Cada comando encapsula tudo o que é necessário para realizar uma ação, tornando seu sistema mais flexível e extensível.

challenge icon

Desafio

Fácil

Vamos criar um sistema inteligente de automação residencial usando o Padrão de Comando! Você criará um sistema no qual vários dispositivos domésticos podem ser controlados por meio de comandos, permitindo que as ações sejam enfileiradas, executadas e até armazenadas para uso posterior, como um controle remoto universal que não precisa saber como cada dispositivo funciona internamente.

Você organizará seu código em quatro arquivos:

  • Command.java: Defina a interface Command que todos os comandos de dispositivos implementarão. Ela deve declarar um único método execute() que executa a ação do comando.
  • Devices.java: Crie duas classes receptoras que representam dispositivos domésticos inteligentes:

    Television - possui métodos powerOn() que imprime TV is now ON, powerOff() que imprime TV is now OFF e setChannel(int channel) que imprime TV channel set to [channel].

    Thermostat - possui métodos setTemperature(int temp) que imprime Thermostat set to [temp] degrees e turnOff() que imprime Thermostat turned OFF.

  • Commands.java: Crie classes de comando concretas que encapsulem operações dos dispositivos:

    TVOnCommand - recebe uma Television em seu construtor e chama powerOn() quando executado.

    TVOffCommand - recebe uma Television em seu construtor e chama powerOff() quando executado.

    TVChannelCommand - recebe uma Television e um int channel em seu construtor e chama setChannel() com esse canal quando executado.

    ThermostatSetCommand - recebe um Thermostat e um int temperature em seu construtor e chama setTemperature() com esse valor quando executado.

  • Main.java: Crie uma classe RemoteControl (o solicitante) que tenha um método setCommand(Command cmd) para armazenar um comando e pressButton() para executar o comando armazenado.

    Em seu método principal, você receberá duas entradas: um número de canal de TV (inteiro) e uma temperatura do termostato (inteiro).

    Crie uma Television e um Thermostat. Crie um RemoteControl e demonstre o Padrão de Comando:

    1. Defina um TVOnCommand e pressione o botão
    2. Defina um TVChannelCommand com o canal informado e pressione o botão
    3. Defina um ThermostatSetCommand com a temperatura informada e pressione o botão
    4. Defina um TVOffCommand e pressione o botão

Você receberá duas entradas, nesta ordem: o canal da TV (inteiro) e a temperatura do termostato (inteiro).

Por exemplo, com as entradas 5 e 72, sua saída seria:

TV is now ON
TV channel set to 5
Thermostat set to 72 degrees
TV is now OFF

Observe como o RemoteControl nunca interage diretamente com os dispositivos. Ele conhece apenas a interface Command. Cada comando encapsula tudo o que é necessário para executar sua ação, facilitando a adição de novos dispositivos e comandos sem alterar o solicitante!

Experimente você mesmo

import java.util.Scanner;

// TODO: Crie a classe RemoteControl (o invocador) com:
// - método setCommand(Command cmd) para armazenar um comando
// - método pressButton() para executar o comando armazenado

class RemoteControl {
    // TODO: Implemente RemoteControl
}

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Leia as entradas
        int channel = scanner.nextInt();
        int temperature = scanner.nextInt();
        
        // TODO: Crie uma Television e um Thermostat
        
        // TODO: Crie um RemoteControl
        
        // TODO: Demonstre o Command Pattern:
        // 1. Defina um TVOnCommand e pressione o botão
        // 2. Defina um TVChannelCommand com o canal de entrada e pressione o botão
        // 3. Set a ThermostatSetCommand with the input temperature and press the button
        // 4. Defina um TVOffCommand e pressione o botão
        
        scanner.close();
    }
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Compilador de Java online