Command

Resumo

O Padrão Command encapsula uma solicitação como um objeto, o que lhe permite parametrizar outros objetos com diferentes solicitações, enfileirar ou registrar solicitações e implementar recursos de cancelamento de operações.

A principal motivação do uso do padrão Command é que algumas vezes é necessário emitir solicitações para objetos sem nada saber sobre a operação que está sendo solicitada ou sobre seu receptor .

Como exemplos de uso do padrão temos menus e controles, que são aplicações que possuem apenas comandos (ações) para serem executados através deles.

O padrão

O padrão Command, também conhecido por Action ou Transaction, é um padrão simples e muito utilizado. Porém ele possui alguns detalhes importantes que precisam ser notados, caso contrário sua implementação pode não trazer tanta reutilização.

O Command tem como objetivo encapsular uma solicitação como um objeto, o que permite parametrizar outros objetos com diferentes solicitações, enfileirar ou registrar solicitações e implementar recursos de cancelamento de operações (desfazer). Ou seja, o objetivo do padrão é transformar um método de uma classe em um objeto, o qual pode executar a ação deste método.

O livro Padrões de Projeto de Erich Gamma diz que a principal motivação do Command é que algumas vezes é necessário emitir solicitações para objetos sem nada saber sobre a operação que está sendo solicitada ou sobre seu receptor. Exemplificando o que o livro diz, imagine um portão eletrônico que você queira abrir, não é necessário saber como funciona o mecanismo que faz o portão abrir ou de que o portão é feito, você apenas quer abrir o portão e por isso aperta um botão que faz ele abrir.

Na figura 1 é apresentado o diagrama de classes do Padrão Command.

Diagrama de Classes

Figura 1 – Diagrama de Classes

Participantes

Visto o diagrama de classes e seus participantes agora vamos entender a implementação com um exemplo de um Portão Eletrônico que possui um controle que faz o portão abrir e fechar. Na figura 2 está a implementação do Portão.

Classe Portao

Figura 2 – Classe Portao

A classe portão possui um atributo estado, onde quando for igual a 0, o portão está aberto, enquanto for igual a 1 o portão está fechado. A classe também possui o método abrir que abre o portão e o método fechar que fecha o portão.

Interface Command

Figura 3 – Interface Command

Na figura 3 está representado a interface Command, que possui o método execute e também o método undo, o qual é opcional, porque nem todas as ações possibilitam uma operação de desfazer.

Classe AbrirCommand

Figura 4 – Classe AbrirCommand

Na figura 4 é apresentado a classe AbrirCommand, que é um ConcreteCommand, sua funcionalidade é fazer um portão abrir através do método execute. Para isto, a classe traz um atributo do tipo portão, que precisa ser “setado“ através do construtor. Além de abrir o portão essa classe também possibilita desfazer a operação de abrir, através do método undo que faz o oposto do execute, fechando o portão.

Classe Controle

Figura 5 – Classe Controle

Na figura 5 é mostrado a classe Controle que é o Invoker, ela armazena Commands e chama o método execute do command. Além disto, ela possui um outro atributo command (ultimoCommand) que armazena o ultimo command que foi usado, através disso, o controle possui um método desfazer que chama o método undo do ultimo command utilizado.

A principal consequência do Command é que ele desacopla o objeto que invoca a operação daquele que sabe como executá-la. Ao visualizar o diagrama de sequência na figura 2 ficará mais claro como isto ocorre.

Diagrama de Sequência

Figura 6 – Diagrama de Sequência

Primeiro o Client cria um novo Command especificando seu Receiver, em seguida este Command é armazenado em um Invoker. O Invoker quando quer chamar a ação do Receiver, usa o método execute do Command que por sua vez chama a ação do Receiver. Deste modo o Invoker não conhece como funciona a ação e também não conhece o Receiver.

Para conhecer mais sobre o padrão recomendo que baixem o slide disponível, olhem o exemplo implementado e que façam a atividade prática proposta. Também é interessante ler as referências que foram utilizadas para este trabalho.

Referências

AnexoApresentação (.zip)
AnexoExercício prático (.zip)

Por: Luiz Serra e Matheus Matos.