image

Access unlimited bootcamps and 650+ courses forever

60
%OFF
Giovanni Rozza
Giovanni Rozza01/05/2023 22:50
Share

[sw design pattern] Command (Comando)

    Os padrões de design GoF são classificados em três categorias: Criacionais, Comportamentais e Estruturais. Os padrões criacionais tratam da criação de objetos, enquanto os padrões estruturais lidam com a estrutura das classes, como herança e composição. Por fim, os padrões comportamentais lidam com a comunicação entre objetos e suas interações. Estes padrões de projeto se encontram no livro “Padrões de Projetos: Soluções Reutilizáveis de Software Orientado a Objetos” escrito por 4 autores denominados GoF (Gang of Four).

    O padrão Command encapsula uma solicitação como um objeto, permitindo que você parametrize clientes com diferentes solicitações, enfileire ou registre solicitações e implemente recursos de cancelamento de operações. Ele também promove o desacoplamento entre emissor e receptor de uma solicitação. Em outras palavras, o padrão Command permite que você transforme operações em objetos, tornando-os mais flexíveis e independentes do sistema que as utiliza.

    O padrão Command é formado pelos seguintes elementos:

    --> Comando (Command): Define uma interface para todos os comandos concretos. Essa interface geralmente contém um único método chamado execute() que é usado para invocar a ação associada ao comando.

    --> Comando Concreto (Concrete Command): Implementa a interface Command e contém uma instância do receptor da solicitação. Esse comando define o vínculo entre o receptor e a ação a ser executada.

    --> Emissor (Invoker): É responsável por invocar os comandos concretos. Ele geralmente contém uma coleção de comandos, podendo enfileirá-los, registrá-los, desfazer suas ações, entre outras operações.

    --> Receptor (Receiver): É o objeto que executa a ação associada ao comando. Ele contém a lógica de negócio específica.

    O padrão de design Command é utilizado para encapsular uma solicitação como um objeto, permitindo que você parametrize clientes com diferentes solicitações, enfileire ou registre solicitações e execute-as em momentos diferentes. Este padrão tem relação com outros padrões, como o Chain of Responsibility, Mediator e Observer. O Chain of Responsibility passa uma solicitação sequencialmente ao longo de uma cadeia dinâmica de possíveis receptores até que um deles a manipule.

    Já o padrão Mediator define um objeto que encapsula como um conjunto de objetos interagem. O Command pode ser usado para implementar solicitações que são enviadas entre objetos Mediator. O padrão Observer permite que objetos sejam notificados quando o estado interno de outro objeto muda. O padrão Command pode ser usado para implementar essas notificações, permitindo que os assinantes sejam configurados em tempo de execução. O padrão Command também pode ser usado em conjunto com outros padrões de design, como o Strategy e o Collection, para atender a diferentes necessidades de projeto.

    Aqui está um exemplo em Java que ilustra o padrão de design Command:

    Suponha que temos um controle remoto que pode ligar/desligar uma luz. Para implementar o padrão de design Command, precisamos criar uma interface Command que define um método execute() que será implementado por todas as classes de comando concretas. Em seguida, criamos classes de comando concretas, como TurnOnLightCommand e TurnOffLightCommand, que implementam a interface Command. Por fim, criamos uma classe RemoteControl que mantém uma referência a um objeto de comando e pode executar um comando chamando seu método execute().

    // Define a interface Command
    interface Command {
      void execute();
    }
    
    
    // Define a classe de comando concreta TurnOnLightCommand
    class TurnOnLightCommand implements Command {
      private Light light;
      
      public TurnOnLightCommand(Light light) {
          this.light = light;
      }
      
      public void execute() {
          light.turnOn();
      }
    }
    
    
    // Define a classe de comando concreta TurnOffLightCommand
    class TurnOffLightCommand implements Command {
      private Light light;
      
      public TurnOffLightCommand(Light light) {
          this.light = light;
      }
      
      public void execute() {
          light.turnOff();
      }
    }
    
    
    // Define a classe Receiver Light
    class Light {
      public void turnOn() {
          System.out.println("Luz ligada!");
      }
      
      public void turnOff() {
          System.out.println("Luz desligada!");
      }
    }
    
    
    // Define a classe RemoteControl
    class RemoteControl {
      private Command command;
      
      public void setCommand(Command command) {
          this.command = command;
      }
      
      public void pressButton() {
          command.execute();
      }
    }
    
    
    // Teste do controle remoto
    public class Main {
      public static void main(String[] args) {
          // Cria o objeto Light (o Receiver)
          Light light = new Light();
          
          // Cria os objetos de comando TurnOnLightCommand e TurnOffLightCommand
          TurnOnLightCommand turnOnCommand = new TurnOnLightCommand(light);
          TurnOffLightCommand turnOffCommand = new TurnOffLightCommand(light);
          
          // Cria o objeto RemoteControl
          RemoteControl remote = new RemoteControl();
          
          // Configura o controle remoto com o comando TurnOnLightCommand
          remote.setCommand(turnOnCommand);
          
          // Pressiona o botão para ligar a luz
          remote.pressButton();
          
          // Configura o controle remoto com o comando TurnOffLightCommand
          remote.setCommand(turnOffCommand);
          
          // Pressiona o botão para desligar a luz
          remote.pressButton();
      }
    }
    

    A saída deste programa será:

    Luz ligada!
    Luz desligada!
    

    links externos com mais exemplos em Java:

    —> No artigo abaixo o código fornecido, a interface TextFileOperation é a interface para todos os comandos concretos. A classe OpenTextFileOperation e SaveTextFileOperation são duas implementações concretas da interface TextFileOperation. A classe TextFile é o receptor, que executa a solicitação específica. A classe TextFileOperationExecutor é o invocador, que executa o comando solicitado.

    Quando o programa é executado, o objeto TextFileOperationExecutor é criado. Em seguida, são executadas duas operações de arquivo de texto: abrir o arquivo "file1.txt" e salvar o arquivo "file2.txt". Para executar cada operação, um objeto de comando é criado, passando um objeto TextFile relevante para cada operação. Em seguida, a operação é adicionada à lista de operações de arquivo de texto e executada pelo executor.

    https://www.baeldung.com/java-command-pattern

    —>Na implementação do exemplo abaixo, a classe Command é uma classe abstrata que fornece métodos para cortar, copiar e colar em um editor de texto. As classes CutCommand, CopyCommand e PasteCommand estendem a classe Command e fornecem suas próprias implementações para o método execute(). Por fim, a classe CommandHistory é uma classe auxiliar que armazena todos os comandos executados em uma pilha para possibilitar a operação undo().

    Em resumo, o exemplo implementa um editor de texto que possui três comandos: copiar, cortar e colar, com suporte para undo. Quando o usuário executa um desses comandos, o editor o armazena em um objeto Command e o adiciona a uma lista de histórico. Quando o usuário solicita a operação undo, o editor remove o comando mais recente do histórico e executa sua operação desfazer correspondente.

    https://refactoring.guru/design-patterns/command/java/example#example-0--commands-PasteCommand-java

    —> O código fornecido no exemplo abaixo simula compra e venda de ativos em uma bolsa de valores. A classe Order é uma interface que declara o método execute(), que será implementado pelas classes BuyStock e SellStock. Essas classes, por sua vez, implementam a interface Order e usam a classe Stock para comprar ou vender uma ação.

    A classe Broker gerencia uma lista de objetos Order permitindo que novas ordens sejam adicionadas e, em seguida, execute todas as ordens na lista usando o método placeOrders().

    Por fim, na classe CommandPatternDemo, o programa cria um objeto Stock, um objeto BuyStock, um objeto SellStock e um objeto Broker. Em seguida, adiciona as ordens de compra e venda ao Broker e as executa usando o método placeOrders().

    Em resumo, o código demonstra como o padrão de design Command permite encapsular solicitações como objetos, permitindo que diferentes objetos sejam parametrizados com diferentes solicitações, registrando e desfazendo operações.

    https://www.tutorialspoint.com/design_pattern/command_pattern.htm

    REFERÊNCIAS:

    https://stackoverflow.com/questions/44006704/gof-design-patterns-applicability-in-what-scenarioshttps://softwareengineering.stackexchange.com/questions/49084/gof-design-patterns-which-ones-do-you-actually-usehttps://refactoring.guru/design-patterns/commandhttps://learn.microsoft.com/en-us/shows/Visual-Studio-Toolbox/Design-Patterns-CommandMementohttps://stackoverflow.com/questions/3883692/using-a-strategy-pattern-and-a-command-pattern

    Share
    Comments (0)