Difference between revisions of "Comando (padrão de desenho)"

From Wiki**3

 
(Exemplo)
 
(20 intermediate revisions by the same user not shown)
Line 1: Line 1:
Material correspondente à aula 23.
+
{{NAVPO}}
 +
{{TOCright}}
 +
O padrão comando permite encapsular um comando ou pedido num objecto. Assim, os clientes podem ser parametrizados com comandos variados e os comandos podem ser manipulados para atingir vários fins: é possível atrasar a sua execução, colocá-los em filas de espera e registar a sua execução. É ainda possível suportar a execução da inversão das acções das operações relativas a um comando (''undo'').
  
[[category:PO 2005/2006]]
+
== Estrutura ==
 +
 
 +
===Diagrama de classes===
 +
 
 +
O padrão comando tem a seguinte estrutura de classes:
 +
 
 +
[[Image:command-dpcd.png|600px]]
 +
 
 +
===Diagrama de sequência===
 +
 
 +
As colaborações entre os intervenientes são as que figuram no seguinte diagrama de sequência:
 +
 
 +
[[Image:command-dpsd.png|450px]]
 +
 
 +
== Exemplo ==
 +
 
 +
Considerando o código na biblioteca '''po-uuilib''' (ver link abaixo), podem ser definidos comando como os seguintes.
 +
 
 +
Cada subclasse de '''Command''' deve providenciar o tipo do "receiver", assim como a instância (a superclasse -- '''Command''' -- apenas suporta um receptor de comandos, mas é possível definir outros que sejam necessários nas subclasses).
 +
 
 +
Exemplo de subclasse de '''Command''' (neste caso, apresenta-se, apenas a título de exemplo, uma operação fictícia sobre o tipo '''Cat''', suposto definido):
 +
<source lang="java">
 +
public class DoChaseLaserDot extends Command<Cat> {
 +
        public DoChaseLaserDot(Cat receiver) {
 +
                super(Label.CHASE_LASER_DOT, receiver);
 +
        }
 +
 
 +
        public final void execute() {
 +
          // DO SOMETHING
 +
        }
 +
}
 +
</source>
 +
 
 +
Exemplo de definição de subclasse de '''Command''', fazendo uso da funcionalidade de validação dinâmica dos comandos (os comandos por omissão são sempre válidos -- ver código). Neste exemplo, assume-se que o método '''isReady''' está definido na classe '''Cat'''. O menu não apresentará o comando e não permitirá a sua invocação. No entanto, o método '''execute''' não é afectado (esta opção destina-se a simplificar as decisões, mas pode ter consequências imprevisíveis se um comando inválido for executado sem o teste ser efectuado).
 +
<source lang="java">
 +
public class DoChaseLaserDot extends Command<Cat> {
 +
        public DoChaseLaserDot(Cat receiver) {
 +
                super(Label.CHASE_LASER_DOT, receiver, receiver -> receiver.isReady());
 +
        }
 +
 
 +
        public final void execute() {
 +
          // DO SOMETHING
 +
        }
 +
}
 +
</source>
 +
 
 +
A definição do método '''isValid''' é inteiramente dependente do domínio. Por omissão, o predicado é sempre verdadeiro.
 +
 
 +
== Exercícios ==
 +
 
 +
* [[Comando (padrão de desenho)/Banco, Conta, Titular (aplicação bancária)|Banco, Conta, Titular (aplicação bancária)]]
 +
 
 +
[[category:Ensino]]
 +
[[category:PO]]

Latest revision as of 18:09, 25 October 2021

Programação com Objectos
Introduction
Creation and Destruction
Inheritance & Composition
Abstraction & Polymorphism
Code Organization
Java Topics
Inner Classes
Enumerations
Data Structures
Exceptions
Input/Output
RTTI
Other Topics
JUnit Tests
UML Topics
Design Patterns
"Simple" Factory
Composite & Visitor
Command
Strategy & State
Template Method
Observer
Abstract Factory
Decorator & Adapter
Façade (aka Facade)

O padrão comando permite encapsular um comando ou pedido num objecto. Assim, os clientes podem ser parametrizados com comandos variados e os comandos podem ser manipulados para atingir vários fins: é possível atrasar a sua execução, colocá-los em filas de espera e registar a sua execução. É ainda possível suportar a execução da inversão das acções das operações relativas a um comando (undo).

Estrutura

Diagrama de classes

O padrão comando tem a seguinte estrutura de classes:

Command-dpcd.png

Diagrama de sequência

As colaborações entre os intervenientes são as que figuram no seguinte diagrama de sequência:

Command-dpsd.png

Exemplo

Considerando o código na biblioteca po-uuilib (ver link abaixo), podem ser definidos comando como os seguintes.

Cada subclasse de Command deve providenciar o tipo do "receiver", assim como a instância (a superclasse -- Command -- apenas suporta um receptor de comandos, mas é possível definir outros que sejam necessários nas subclasses).

Exemplo de subclasse de Command (neste caso, apresenta-se, apenas a título de exemplo, uma operação fictícia sobre o tipo Cat, suposto definido):

public class DoChaseLaserDot extends Command<Cat> {
        public DoChaseLaserDot(Cat receiver) {
                super(Label.CHASE_LASER_DOT, receiver);
        }

        public final void execute() {
          // DO SOMETHING
        }
}

Exemplo de definição de subclasse de Command, fazendo uso da funcionalidade de validação dinâmica dos comandos (os comandos por omissão são sempre válidos -- ver código). Neste exemplo, assume-se que o método isReady está definido na classe Cat. O menu não apresentará o comando e não permitirá a sua invocação. No entanto, o método execute não é afectado (esta opção destina-se a simplificar as decisões, mas pode ter consequências imprevisíveis se um comando inválido for executado sem o teste ser efectuado).

public class DoChaseLaserDot extends Command<Cat> {
        public DoChaseLaserDot(Cat receiver) {
                super(Label.CHASE_LASER_DOT, receiver, receiver -> receiver.isReady());
        }

        public final void execute() {
          // DO SOMETHING
        }
}

A definição do método isValid é inteiramente dependente do domínio. Por omissão, o predicado é sempre verdadeiro.

Exercícios