Menu
Coddy logo textTech

Padrão Command

Parte da seção Programação Orientada a Objetos do Journey de C# da Coddy. Lição 56 de 70.

O padrão Command é um padrão comportamental 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, enfileirá-las, registrá-las ou oferecer suporte a operações que podem ser desfeitas.

O padrão separa o objeto que invoca uma operação do objeto que sabe como executá-la. Ele consiste em quatro componentes principais: uma interface de comando, comandos concretos, um receptor (o objeto que realiza o trabalho de fato) e um invocador (o objeto que aciona os comandos).

public interface ICommand
{
    void Execute();
}

public class Light  // Receptor
{
    public void TurnOn() => Console.WriteLine("Light is ON");
    public void TurnOff() => Console.WriteLine("Light is OFF");
}

public class TurnOnCommand : ICommand
{
    private Light _light;
    
    public TurnOnCommand(Light light) => _light = light;
    
    public void Execute() => _light.TurnOn();
}

public class TurnOffCommand : ICommand
{
    private Light _light;
    
    public TurnOffCommand(Light light) => _light = light;
    
    public void Execute() => _light.TurnOff();
}

O invocador armazena e executa comandos sem saber o que eles fazem:

public class RemoteControl  // Invocador
{
    private ICommand _command;
    
    public void SetCommand(ICommand command) => _command = command;
    
    public void PressButton() => _command.Execute();
}

// Uso
var light = new Light();
var remote = new RemoteControl();

remote.SetCommand(new TurnOnCommand(light));
remote.PressButton();  // Luz está LIGADA

remote.SetCommand(new TurnOffCommand(light));
remote.PressButton();  // Luz está DESLIGADA

O padrão Command é particularmente poderoso para implementar a funcionalidade de desfazer, a gravação de macros ou o enfileiramento de operações 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 de comandos para um editor de texto usando o padrão Command. Você criará um sistema no qual operações de edição, como inserir e excluir texto, são encapsuladas como objetos de comando, permitindo que o editor as execute por meio de uma interface unificada.

Você organizará seu código em três arquivos:

  • Command.cs: Defina uma interface ICommand no namespace TextEditor com um único método Execute(). Em seguida, crie duas classes de comando concretas:
    • InsertCommand - recebe um Document e uma string text em seu construtor. Quando executado, acrescenta o texto ao documento e imprime Inserted: {text}
    • DeleteCommand - recebe um Document e um int count em seu construtor. Quando executado, remove os últimos count caracteres do documento e imprime Deleted: {count} characters
  • Document.cs: Crie uma classe Document no mesmo namespace. Este é o receptor — o objeto que realmente executa as operações de texto. Ele deve ter:
    • Um campo privado do tipo string para armazenar o conteúdo (inicializado como uma string vazia)
    • Um método Append(string text) que adiciona texto ao conteúdo
    • Um método RemoveLast(int count) que remove os últimos count caracteres (se count exceder o comprimento do conteúdo, limpa todo o conteúdo)
    • Um método GetContent() que retorna o conteúdo atual
  • Program.cs: Crie uma classe Editor que atua como o invocador. Ela deve ter um método SetCommand(ICommand command) e um método ExecuteCommand() que executa o comando atual. No seu código principal, demonstre o padrão Command processando uma série de operações de edição.

Você receberá as seguintes entradas:

  • Número de comandos a executar
  • Para cada comando: o tipo de comando (insert ou delete), seguido pelo texto a inserir ou pelo número de caracteres a excluir

Depois de executar todos os comandos, imprima o conteúdo final do documento em uma nova linha com o formato Content: {content}.

Por exemplo, se as entradas forem:

4
insert
Hello
insert
 World
delete
3
insert
!

A saída deverá ser:

Inserted: Hello
Inserted:  World
Deleted: 3 characters
Inserted: !
Content: Hello Wo!

Observe como o Editor (invocador) não sabe nada sobre a manipulação de texto — ele simplesmente executa qualquer comando que receba. Os comandos encapsulam tanto a ação quanto o receptor, facilitando a adição de novas operações, como ReplaceCommand, sem alterar o editor!

Experimente você mesmo

using System;
using TextEditor;

// TODO: Crie a classe Editor (o invoker)
public class Editor
{
    // TODO: Adicione um campo privado para armazenar o comando atual
    private ICommand _command;

    // TODO: Implemente o método SetCommand
    public void SetCommand(ICommand command)
    {
        // TODO: Armazene o comando
    }

    // TODO: Implemente o método ExecuteCommand
    public void ExecuteCommand()
    {
        // TODO: Execute o comando atual
    }
}

class Program
{
    public static void Main(string[] args)
    {
        // Leia o número de comandos
        int n = Convert.ToInt32(Console.ReadLine());

        // Crie o documento (receiver)
        Document document = new Document();

        // Crie o editor (invoker)
        Editor editor = new Editor();

        // TODO: Processe cada comando
        for (int i = 0; i < n; i++)
        {
            string commandType = Console.ReadLine();

            // TODO: Com base no commandType, crie o comando apropriado
            // - Se for "insert": leia o texto e crie o InsertCommand
            // - Se for "delete": leia a contagem e crie o DeleteCommand
            // Em seguida, defina o comando no editor e execute-o
        }

        // TODO: Imprima o conteúdo final com o formato "Content: {content}"
    }
}
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 C# online