Padrão Command: Encapsulando solicitações e separando ação e execução

Fundamentos do Padrão Command

O Padrão Command é uma dessas técnicas, sendo extremamente útil quando se trata de encapsular solicitações como objetos. De forma simplificada, a ideia é separar quem solicita uma ação do objeto que a executa, tornando o processo mais organizado e eficiente.

Encapsulamento de solicitações: a ação e a execução

Entendendo o encapsulamento de solicitações

Mas o que significa encapsular solicitações? Bom, imagine que você tem uma série de ações que precisa executar. Ao invés de chamar cada uma dessas ações diretamente, você cria um objeto “Command” que encapsula essas ações. Assim, quem solicita não precisa conhecer o “como”, apenas o “o que” deve ser feito.

Benefícios do Padrão Command

Os principais benefícios

Esse processo pode parecer complexo em um primeiro momento, mas traz uma série de benefícios. Entre eles, destaco a flexibilidade, a reutilização de código e a capacidade de implementar recursos como desfazer e refazer ações.

Flexibilidade com o Padrão Command

Como o Padrão Command garante flexibilidade

Com o padrão Command, é possível modificar as ações encapsuladas sem afetar quem as chamou. Isso significa que você tem a flexibilidade de alterar a lógica de negócios sem causar grandes impactos no sistema.

Reutilização de código através do Padrão Command

Evitando a repetição de código

Outro grande benefício do Padrão Command é a possibilidade de reutilização de código. Com as solicitações encapsuladas, você pode utilizá-las em diferentes partes do seu sistema, evitando repetição e tornando o código mais limpo e fácil de entender.

Implementando desfazer e refazer ações

Funcionalidades úteis com o Padrão Command

Imagine que você precisa implementar uma funcionalidade de desfazer/refazer ações. Com o padrão Command, isso se torna muito mais simples. Isso porque cada comando sabe exatamente como desfazer a ação que ele mesmo executou.

Exemplo de implementação em C#

C#
// A interface Command define o contrato para todos os objetos de comando
public interface ICommand
{
    void Executar();
    void Desfazer();
}

// Objetos de comando concretos que implementam a interface ICommand
public class ComandoLigarLuz : ICommand
{
    private Luz luz;

    public ComandoLigarLuz(Luz luz)
    {
        this.luz = luz;
    }

    public void Executar()
    {
        luz.Ligar();
    }

    public void Desfazer()
    {
        luz.Desligar();
    }
}

public class ComandoDesligarLuz : ICommand
{
    private Luz luz;

    public ComandoDesligarLuz(Luz luz)
    {
        this.luz = luz;
    }

    public void Executar()
    {
        luz.Desligar();
    }

    public void Desfazer()
    {
        luz.Ligar();
    }
}

// A classe Receptor que realiza as ações reais
public class Luz
{
    public void Ligar()
    {
        Console.WriteLine("Luz ligada");
    }

    public void Desligar()
    {
        Console.WriteLine("Luz desligada");
    }
}

// A classe Invocador que utiliza os objetos de comando
public class ControleRemoto
{
    private ICommand comando;

    public void DefinirComando(ICommand comando)
    {
        this.comando = comando;
    }

    public void ExecutarComando()
    {
        comando.Executar();
    }

    public void DesfazerComando()
    {
        comando.Desfazer();
    }
}

// Código do cliente que utiliza o ControleRemoto e os comandos
public class Cliente
{
    public static void Main(string[] args)
    {
        ControleRemoto controleRemoto = new ControleRemoto();

        Luz luzSalaEstar = new Luz();
        ComandoLigarLuz comandoLigarLuzSalaEstar = new ComandoLigarLuz(luzSalaEstar);
        ComandoDesligarLuz comandoDesligarLuzSalaEstar = new ComandoDesligarLuz(luzSalaEstar);

        controleRemoto.DefinirComando(comandoLigarLuzSalaEstar);
        controleRemoto.ExecutarComando(); // Liga a luz da sala de estar

        controleRemoto.DefinirComando(comandoDesligarLuzSalaEstar);
        controleRemoto.ExecutarComando(); // Desliga a luz da sala de estar

        controleRemoto.DesfazerComando(); // Desfaz o último comando (liga a luz da sala de estar)

        Console.ReadLine();
    }
}

//Fonte: ChatGPT

Neste exemplo, temos a classe Luz que representa o receptor do comando. Definimos a interface ICommand que especifica os métodos Executar() e Desfazer(). As classes ComandoLigarLuz e ComandoDesligarLuz implementam essa interface e encapsulam as ações correspondentes de ligar e desligar a luz.

A classe ControleRemoto age como o invocador, que define o comando e o executa quando necessário. Finalmente, no código do cliente, criamos uma instância de ControleRemoto e configuramos com os comandos apropriados para controlar o objeto Luz.

Este exemplo demonstra como o padrão Command encapsula solicitações como objetos, permitindo a separação entre quem solicita uma ação e o objeto que a executa, proporcionando flexibilidade, reutilização de código e a capacidade de implementar recursos como desfazer e refazer ações.

Exemplo de implementação em Java

Java
// Interface Command que define o contrato para os comandos
interface Command {
    void execute();
}

// Classe que representa um comando concreto
class ConcreteCommand implements Command {
    private Receiver receiver;

    public ConcreteCommand(Receiver receiver) {
        this.receiver = receiver;
    }

    public void execute() {
        receiver.action();
    }
}

// Classe que atua como o receptor da solicitação
class Receiver {
    public void action() {
        System.out.println("Ação executada pelo Receiver");
    }
}

// Classe que atua como o invocador
class Invoker {
    private Command command;

    public void setCommand(Command command) {
        this.command = command;
    }

    public void executeCommand() {
        command.execute();
    }
}

// Classe de exemplo que utiliza o padrão Command
public class Main {
    public static void main(String[] args) {
        // Criando o invocador
        Invoker invoker = new Invoker();

        // Criando o receiver
        Receiver receiver = new Receiver();

        // Criando o comando concreto e passando o receiver para ele
        Command command = new ConcreteCommand(receiver);

        // Configurando o comando no invocador
        invoker.setCommand(command);

        // Executando o comando através do invocador
        invoker.executeCommand();
    }
}

// Fonte: ChatGPT

Neste exemplo, temos a interface Command que define o contrato para os comandos. A classe ConcreteCommand implementa essa interface e representa um comando concreto que encapsula a ação a ser executada. A classe Receiver atua como o receptor da solicitação e possui a lógica da ação a ser executada. A classe Invoker atua como o invocador, que é responsável por executar o comando. Por fim, na classe Main, criamos um exemplo onde configuramos o comando no invocador e executamos o comando através dele.

Exemplo de implementação em Python

Python
# Interface Command que define o contrato para os comandos
class Command:
    def execute(self):
        pass

# Classe que representa um comando concreto
class ConcreteCommand(Command):
    def __init__(self, receiver):
        self.receiver = receiver

    def execute(self):
        self.receiver.action()

# Classe que atua como o receptor da solicitação
class Receiver:
    def action(self):
        print("Ação executada pelo Receiver")

# Classe que atua como o invocador
class Invoker:
    def set_command(self, command):
        self.command = command

    def execute_command(self):
        self.command.execute()

# Classe de exemplo que utiliza o padrão Command
if __name__ == "__main__":
    # Criando o invocador
    invoker = Invoker()

    # Criando o receiver
    receiver = Receiver()

    # Criando o comando concreto e passando o receiver para ele
    command = ConcreteCommand(receiver)

    # Configurando o comando no invocador
    invoker.set_command(command)

    # Executando o comando através do invocador
    invoker.execute_command()

# Fonte: ChatGPT

Neste exemplo, temos a classe Command que define o contrato para os comandos. A classe ConcreteCommand herda dessa classe e representa um comando concreto que encapsula a ação a ser executada. A classe Receiver atua como o receptor da solicitação e possui a lógica da ação a ser executada. A classe Invoker atua como o invocador, responsável por executar o comando. Por fim, na classe de exemplo, criamos um exemplo onde configuramos o comando no invocador e executamos o comando através dele.

Modularização e desacoplamento do sistema

Criando um sistema mais organizado

O Padrão Command é um grande aliado quando o assunto é modularização e desacoplamento do sistema. As solicitações encapsuladas permitem criar módulos independentes, tornando o sistema mais flexível e fácil de manter.

Manutenção facilitada

Facilitando o processo de manutenção

Com a modularização e o desacoplamento proporcionados pelo Padrão Command, a manutenção do sistema também se torna mais simples. Isso facilita a identificação de bugs, a correção de problemas e a implementação de novas funcionalidades.

Adaptação às mudanças com o Padrão Command

Preparando o sistema para o futuro

Em um mundo de negócios em constante mudança, a capacidade de adaptação é essencial. Com o padrão Command, seu sistema estará preparado para lidar com as mudanças de forma mais eficiente.

Criando sistemas robustos

Construindo uma arquitetura forte

Em resumo, ao utilizar o Padrão Command, estamos contribuindo para a criação de sistemas mais robustos e eficientes. E, afinal, quem não quer um sistema que funcione bem, seja fácil de manter e esteja preparado para o futuro?

Conclusão

Como você pode ver, o Padrão Command é uma ferramenta poderosa na caixa de ferramentas de qualquer programador. Com ele, é possível criar sistemas mais flexíveis, reutilizar código e implementar recursos úteis como desfazer e refazer ações. Então, da próxima vez que você se deparar com um desafio em seu projeto, lembre-se do Padrão Command.

Esse conteúdo é parte do material disponibilizado para os participantes do meu grupo de estudos de Padrões de Projeto. Você quer participar desse grupo? Clique aqui e veja como funciona.

Dúvidas Frequentes

O que é o Padrão Command?
O Padrão Command é uma técnica de design de software que encapsula solicitações como objetos, separando quem solicita uma ação do objeto que a executa.

Quais são os benefícios do Padrão Command?
O Padrão Command traz benefícios como flexibilidade, reutilização de código e a capacidade de implementar recursos como desfazer e refazer ações.

O Padrão Command facilita a manutenção do sistema?
Sim, com a modularização e o desacoplamento proporcionados pelo Padrão Command, a manutenção do sistema se torna mais simples.

O Padrão Command ajuda na adaptação às mudanças?
Sim, em um mundo de negócios em constante mudança, a capacidade de adaptação é essencial. Com o padrão Command, seu sistema estará preparado para lidar com as mudanças de forma mais eficiente.

Como o Padrão Command contribui para a criação de sistemas robustos?
Ao utilizar o Padrão Command, estamos contribuindo para a criação de sistemas mais robustos e eficientes, que funcionem bem, sejam fáceis de manter e estejam preparados para o futuro.

Quer se aprofundar neste tema?

Então participe do grupo de estudos de Padrões de Projeto.

Desenvolva soluções simples para os problemas mais complexos. Escreva código fácil de entender, mais barato para manter e evoluir.

Participe do
grupo intensivo de

Padrões de Projeto

com

Desenvolva soluções simples para os problemas mais complexos. Escreva código fácil de entender, mais barato para manter e evoluir.

Participe do
grupo intensivo de

Padrões de Projeto

com

Desenvolva soluções simples para os problemas mais complexos. Escreva código fácil de entender, mais barato para manter e evoluir.

Veja outros artigos relacionados

Quer Melhorar Seu Design? Aplique CQS

Nesse mundo cada vez mais acelerado da tecnologia da informação, uma das metas constantes para desenvolvedores é a otimização e...

Você Precisa Conhecer o State Pattern

Em minha jornada como desenvolvedor de software, a descoberta e compreensão do State Pattern foi um divisor de águas, assim...

Como padrões ajudam a reduzir o impacto da escassez de recursos

Quando pensamos em software development, um dos grandes desafios é criar sistemas eficientes especialmente em ambientes com recursos limitados. Diante...

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de DDD do Jeito Certo:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Reputação e Marketing Pessoal:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Reputação e Marketing Pessoal:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Padrões de Projeto:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Padrões de Projeto:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Algoritmos e Estruturas de Dados:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Algoritmos e Estruturas de Dados:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Programa ElemarJR de Aceleração, Do Jeito Certo:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Programa ElemarJR de Aceleração, Do Jeito Certo:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Reputação e Marketing Pessoal:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Reputação e Marketing Pessoal:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Padrões de Projeto:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Padrões de Projeto:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de DDD do Jeito Certo:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de DDD do Jeito Certo:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Algoritmos e Estruturas de Dados:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Algoritmos e Estruturas de Dados:

Mentoria em Arquitetura de Software

Ênfase em Systems Design

Para se candidatar nesta turma aberta, preencha o formulário a seguir:

Reproduzir vídeo

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no curso de Padrão Command: Encapsulando solicitações e separando ação e execução:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no curso de Padrão Command: Encapsulando solicitações e separando ação e execução:

Padrão Command: Encapsulando solicitações e separando ação e execução

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Reputação e Marketing Pessoal:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no curso de Padrão Command: Encapsulando solicitações e separando ação e execução:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de DDD do Jeito Certo:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Padrões de Projeto:

Crie sua conta

Preencha os dados a seguir para iniciar o seu cadastro no Grupo Intensivo de Estudos de Algoritmos e Estruturas de Dados:

× Precisa de ajuda?