Menu
Coddy logo textTech

Padrão Command

Parte da seção Programação Orientada a Objetos do Journey de PHP da Coddy — lição 75 de 91.

O Padrão Command é um padrão de projeto comportamental que transforma uma solicitação em um objeto independente contendo todas as informações sobre a solicitação. Essa transformação permite que você passe solicitações como argumentos de método, atrase ou coloque a execução de uma solicitação em fila e suporte operações que podem ser desfeitas.

Pense em um restaurante.

Quando você pede comida, o garçom escreve seu pedido em uma comanda (o comando), leva-o para a cozinha e o chef o executa. O garçom não precisa saber cozinhar; ele apenas entrega o comando.

Isso desacopla o solicitante do executor.

Aqui está uma implementação básica:

<?php
interface Command {
    public function execute(): string;
}
class Light {
    public function on(): string { return "Light is ON"; }
    public function off(): string { return "Light is OFF"; }
}
class LightOnCommand implements Command {
    public function __construct(private Light $light) {}
    
    public function execute(): string {
        return $this->light->on();
    }
}
class LightOffCommand implements Command {
    public function __construct(private Light $light) {}
    
    public function execute(): string {
        return $this->light->off();
    }
}

O invoker (invocador) aciona comandos sem saber o que eles fazem:

<?php
class RemoteControl {
    public function press(Command $command): string {
        return $command->execute();
    }
}
$light = new Light();
$remote = new RemoteControl();

echo $remote->press(new LightOnCommand($light)) . "\n";
echo $remote->press(new LightOffCommand($light));

Saída:

Light is ON
Light is OFF

O Command Pattern se destaca quando você precisa enfileirar operações, implementar a funcionalidade de desfazer ou registrar ações. Cada comando é independente, facilitando a adição de novos comandos sem modificar o código existente.

challenge icon

Desafio

Fácil

Vamos construir um sistema de comandos para um editor de texto usando o Command Pattern. Editores de texto frequentemente precisam suportar operações como escrever texto, excluir texto e desfazer ações — cada operação se torna um objeto de comando independente que pode ser executado por meio de uma interface unificada.

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

  • Command.php — Defina uma interface Command com um único método execute(): string. Isso estabelece o contrato que todos os comandos do editor devem seguir.
  • TextEditor.php — Crie uma classe TextEditor que representa o receptor — o objeto que realmente realiza o trabalho. Seu editor deve:
    • Armazenar o conteúdo de texto atual (comece com uma string vazia)
    • Ter um método write(string $text): string que anexa o texto ao conteúdo e retorna "Written: [text]"
    • Ter um método clear(): string que esvazia o conteúdo e retorna "Content cleared"
    • Ter um método getContent(): string que retorna o conteúdo atual
  • Commands.php — Inclua os arquivos Command e TextEditor. Crie duas classes de comando que implementam a interface Command:
    • WriteCommand — Recebe um TextEditor e uma string de texto em seu construtor. Seu método execute() chama o método write() do editor e retorna o resultado.
    • ClearCommand — Recebe um TextEditor em seu construtor. Seu método execute() chama o método clear() do editor e retorna o resultado.
  • main.php — Inclua o arquivo Commands. Você receberá duas entradas: um tipo de comando ("write" ou "clear") e uma string de texto (usada apenas para comandos de escrita).

    Crie uma instância de TextEditor. Com base no tipo de comando, crie o objeto de comando apropriado. Em seguida, crie uma função invocadora ou um mecanismo simples que chame execute() no comando e imprima o resultado.

    Em uma nova linha, imprima o conteúdo atual do editor neste formato: Content: [content] (se estiver vazio, apenas imprima Content: sem nada após o espaço).

Este desafio demonstra como o Command Pattern encapsula cada operação como um objeto. O invocador não precisa saber se está executando um comando de escrita ou de limpeza — ele simplesmente chama execute() e deixa o comando cuidar dos detalhes.

Folha de consulta

O Command Pattern (Padrão de Comando) é um padrão de design comportamental que encapsula uma solicitação como um objeto independente contendo todas as informações sobre a solicitação. Isso permite que você passe solicitações como argumentos de método, enfileire operações e suporte ações que podem ser desfeitas.

O padrão desacopla o solicitante (invoker) do executor (receiver), de forma semelhante a como um garçom entrega pedidos a um chef sem precisar saber como cozinhar.

Estrutura Básica

Defina uma interface Command com um método execute():

interface Command {
    public function execute(): string;
}

Crie uma classe receptora (receiver) que realiza o trabalho real:

class Light {
    public function on(): string { return "Light is ON"; }
    public function off(): string { return "Light is OFF"; }
}

Implemente classes de comando concretas que encapsulam ações específicas:

class LightOnCommand implements Command {
    public function __construct(private Light $light) {}
    
    public function execute(): string {
        return $this->light->on();
    }
}

class LightOffCommand implements Command {
    public function __construct(private Light $light) {}
    
    public function execute(): string {
        return $this->light->off();
    }
}

Invoker

O invoker dispara comandos sem conhecer seus detalhes de implementação:

class RemoteControl {
    public function press(Command $command): string {
        return $command->execute();
    }
}

$light = new Light();
$remote = new RemoteControl();

echo $remote->press(new LightOnCommand($light)) . "\n";
echo $remote->press(new LightOffCommand($light));

Benefícios

O Command Pattern é ideal para enfileirar operações, implementar a funcionalidade de desfazer ou registrar ações. Cada comando é independente, facilitando a adição de novos comandos sem modificar o código existente.

Experimente você mesmo

<?php

require_once 'Commands.php';

// Ler a entrada
$commandType = trim(fgets(STDIN)); // "write" ou "clear"
$text = trim(fgets(STDIN));         // texto para o comando write

// TODO: Criar uma instância de TextEditor

// TODO: Com base no tipo de comando, criar o objeto de comando apropriado
// - Se "write", criar um WriteCommand com o editor e o texto
// - Se "clear", criar um ClearCommand com o editor

// TODO: Criar um mecanismo invoker que chama execute() no comando
// e imprime o resultado

// TODO: Imprimir o conteúdo atual do editor no formato: "Content: [content]"
// (se estiver vazio, apenas imprimir "Content: " sem nada após o espaço)

?>
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