Aulas 23 e 24

Padrão COMMAND

Objetivo:

Encapsular uma solicitação como um objeto, permitindo desta forma parametrizar clientes com diferentes solicitações, enfileirar ou fazer o registro (log) de solicitações e suportar operações que podem ser desfeitas.

Também conhecido como: Action ou Transaction.

Motivação:
As vezes precisamos executar uma operação sem se preocupar com qual objeto que vai realiza-la ou simplesmente não conhecemos qual objeto vai receber a delegação para executar tal operação.
Em uma aplicação Client/Servidor geralmente temos o componente Menu que é composto de
vários itens. Cada item do menu eqüivale uma operação, como salvar um arquivo, ler arquivo, apagar arquivo, selecionar a paleta de cores e etc..

Quando selecionamos um item do menu uma operação deve ser realizada. Esta operação pode ser encapsulada em um objeto, assim reduziremos o acoplamento entre o objeto menu e o objeto que executa a operação.
Um outro cenário que podemos ter. Em uma aplicação Web de três camadas, podemos fazer uma requisição para processar dos dados de um formulário esta requisição é delegada para um objeto.
Esta operação pode ser encapsulada em um objeto, assim reduziremos o acoplamento entre o as camadas.

Aplicação:
Use o padrão Command quando você precisa:
-Parametrizar objetos por uma ação a ser executada.

-Especificar, enfileirar e executar solicitações em tempos diferentes. Um objeto Command poder ter o ciclo de vida independente da requisição do cliente.

-Suporte para desfazer operações. A operação "execute" do Command, pode armazenar
estados para reverter seus efeitos no próprio comando. Basta acrescentar na interface
Command uma operação chamada "Unexecute", que terá a responsabilidade de desfazer a
operação realizada pelo "execute". Os comandos realizados podem ser armazenados em lista histórica.

-Estruturar um sistema em torno de operações de alto nível, como transações por
exemplo. Uma transação encapsula um conjunto de mudanças nos dados. O padrão
Command provê uma maneira de modelar transações. O Command tem uma interface comum,
assim podemos chamar todas as transações do mesmo jeito.

-Reduzir acoplamento entre as requisições dos clientes e o objetos que as executam.

Aplicabilidade:
Use o padrão Command para:

Parametrizar objetos por uma ação a ser executada
Tal parametrização pode ser expressada numa linguagem procedural através de uma função callback, ou seja, uma função que é registrada em algum lugar para ser chamada em um momento mais adiante.
Os Commands são uma substituição orientada a objetos para callbacks.

Especificar, enfileirar e executar solicitações em tempos diferentes.
Um objeto Command pode ter um tempo de vida independente da solicitação original.
Se o receptor de uma solicitação pode ser representado de uma maneira independente do espaço de endereçamento, então é possível transferir um objeto command para a solicitação para um processo diferente e lá atender a solicitação.

Suportar desfazer operações.
A operação execute(), de Command, pode armazenar estados para reverter seus efeitos no próprio comando.
A interface de Command pode ter acrescentada uma operação unexecute(), que reverte os efeitos de uma chamada anterior de execute().
Os comandos executados são armazenados em uma lista histórica.
O nível ilimitado de desfazer e refazer operações é obtido percorrendo esta lista para trás e para frente, chamando operações unexecute() e execute(), respectivamente.

Suportar o registro (logging) de mudanças de maneira que possam ser reaplicadas no caso de uma queda de sistema.
Ao aumentar a interface de Command com as operações carregar() e armazenar(), pode-se manter um registro (log) persistente das mudanças.
A recuperação de uma queda de sistema envolve a recarga dos comandos registrados a partir do disco e sua reexecução com a operação execute().

Estruturar um sistema em torno de operações de alto nível construídas sobre operações primitivas.
Tal estrutura é comum em sistemas de informação que suportam transações.
Uma transação encapsula um conjunto de mudanças nos dados.
O padrão Command fornece uma maneira de modelar transações.
Os Commands têm uma interface comum, permitindo invocar todas as transações da mesma maneira.
O padrão também torna mais fácil estender o sistema com novas transações.


EXEMPLO:


public class DvdName {
private String titleName;

public DvdName(String titleName) {
this.setTitleName(titleName);
}

public final void setTitleName(String titleNameIn) {
this.titleName = titleNameIn;
}
public final String getTitleName() {
return this.titleName;
}

public void setNameStarsOn() {
this.setTitleName(this.getTitleName().replace(' ','*'));
}
public void setNameStarsOff() {
this.setTitleName(this.getTitleName().replace('*',' '));
}

public String toString() {
return ("DVD: " + this.getTitleName());
}
}


public abstract class CommandAbstract {
public abstract void execute();
}


public class DvdCommandNameStarsOn extends CommandAbstract {
private DvdName dvdName;

public DvdCommandNameStarsOn(DvdName dvdNameIn) {
this.dvdName = dvdNameIn;
}
public void execute() {
this.dvdName.setNameStarsOn();
}
}


public class DvdCommandNameStarsOff extends CommandAbstract {
private DvdName dvdName;

public DvdCommandNameStarsOff(DvdName dvdNameIn) {
this.dvdName = dvdNameIn;
}
public void execute() {
this.dvdName.setNameStarsOff();
}
}


class TestCommand {
public static void main(String[] args) {
DvdName jayAndBob =
new DvdName("Jay and Silent Bob Strike Back");
DvdName spongeBob =
new DvdName("Sponge Bob Squarepants - " +
"Nautical Nonsense and Sponge Buddies");
System.out.println("as first instantiated");
System.out.println(jayAndBob.toString());
System.out.println(spongeBob.toString());

CommandAbstract bobStarsOn =
new DvdCommandNameStarsOn(jayAndBob);
CommandAbstract bobStarsOff =
new DvdCommandNameStarsOff(jayAndBob);
CommandAbstract spongeStarsOn =
new DvdCommandNameStarsOn(spongeBob);
CommandAbstract spongeStarsOff =
new DvdCommandNameStarsOff(spongeBob);

bobStarsOn.execute();
spongeStarsOn.execute();
System.out.println(" ");
System.out.println("stars on");
System.out.println(jayAndBob.toString());
System.out.println(spongeBob.toString());

spongeStarsOff.execute();
System.out.println(" ");
System.out.println("sponge stars off");
System.out.println(jayAndBob.toString());
System.out.println(spongeBob.toString());
}
}



UML do Exempo:



Link Referência

0 comentários:

Postar um comentário