Estou com algumas dúvidas relacionadas ao padrão Command. Tenho uma aplicação, cuja interface acessa diversos commands, porém alguns desses commands retornam valores distintos, outros lançam throws e outros recebem alguns parâmetros.
O fato é que com isso fica difícil de escrever uma classe abstrata ou uma interface com um método execute().
Estou tornando o padrão sem propósito ou há alguma alternativa para esse tipo de implementação?
Só tem sentido se você quiser que determinado conjunto de objetos siga uma determinada regra de execução. Mas fazer isso para todo tipo de objeto, note que você vai tornar seu sistema extremamente procedural e seus objetos engessados.
Aproveitando o embalo do topico. Tbm tenho uma duvida sobre o command.
Eu o estou usando da seguinte maneira:
Um command para cada evento, assim a UI manda esse command para um controller q chama o metodo execute do qual estiver instaciado.
O problema nesse caso é o seguinte: Tenho q escrever uma classe command para cada evento da UI. Cada command desse implementa o metodo execute para uma propriedade (uso c#) do objeto ex:
public void execute()
{
venda.data = this.valor; //valor é passado no constructor
}
mas isso na verdade nao refresca muito, da quase no mesmo q o evento na interface chame diretamente o metodo no objeto.
Qual seria um solucao melhor pra esse caso?
Desculpe me meter nesse topico com outra pergunta. Mas achei melhor q criar outro.
[quote=YvGa]Aproveitando o embalo do topico. Tbm tenho uma duvida sobre o command.
Eu o estou usando da seguinte maneira:
Um command para cada evento, assim a UI manda esse command para um controller q chama o metodo execute do qual estiver instaciado.
O problema nesse caso é o seguinte: Tenho q escrever uma classe command para cada evento da UI. Cada command desse implementa o metodo execute para uma propriedade (uso c#) do objeto ex:
public void execute()
{
venda.data = this.valor; //valor é passado no constructor
}
mas isso na verdade nao refresca muito, da quase no mesmo q o evento na interface chame diretamente o metodo no objeto.
Qual seria um solucao melhor pra esse caso?
Desculpe me meter nesse topico com outra pergunta. Mas achei melhor q criar outro.[/quote]
Notou como isso fica procedural?
Para que você precisa de uma classe para cada evento? Não pode existir uma interface que defina os métodos e uma classe só que seja responsável por manipular/executar estes métodos?
Obrigado pela atenção Rafael. Estou usando os commands para executar as ações do menu, porém há casos em que preciso retornar alguma coisa para a interface. E o que fazer?
[quote=Rafael Nunes]Notou como isso fica procedural?
Para que você precisa de uma classe para cada evento? Não pode existir uma interface que defina os métodos e uma classe só que seja responsável por manipular/executar estes métodos?[/quote]
É justamenteo q eu estou procurando, so nao consegui imaginar como fazer isso sem um caminhao de ifs pq o componente GUI só é responsavel por criar o command, quem chama o metodo execute é um controller. Se eu fizer só uma classe teria q implementar cada metodo dessa classe no controller.
Ou xeje, to com cobertor curto. Ou faco muitos commands ou faco muitos metodos no controller o q dificultaria muito a criacao de um controller abstrato.
Estou procurando alguma coisa com reflection e delegate, mas ate agora nao saiu nada q prestasse.
Não há como parametrizar de forma genérica este retorno?
[quote=YvGa]É justamenteo q eu estou procurando, so nao consegui imaginar como fazer isso sem um caminhao de ifs pq o componente GUI só é responsavel por criar o command, quem chama o metodo execute é um controller. Se eu fizer só uma classe teria q implementar cada metodo dessa classe no controller.
Ou xeje, to com cobertor curto. Ou faco muitos commands ou faco muitos metodos no controller o q dificultaria muito a criacao de um controller abstrato.
Estou procurando alguma coisa com reflection e delegate, mas ate agora nao saiu nada q prestasse.[/quote]
Num caso destes, particularmente eu utilizaria um COmmand, apesar de não ficar muito ‘elegante’ na minha opinião. Cada componente do menu tem uma classe respectiva, certo? Então crie um command para cada também.
Aliás, olhando no próprio livro do GoF, o exemplo que eles utilizam para COmmand é exatamente este teu caso.
[quote=Rafael Nunes
Num caso destes, particularmente eu utilizaria um COmmand, apesar de não ficar muito ‘elegante’ na minha opinião. Cada componente do menu tem uma classe respectiva, certo? Então crie um command para cada também.
Aliás, olhando no próprio livro do GoF, o exemplo que eles utilizam para COmmand é exatamente este teu caso.[/quote]
http://www.codeproject.com/cs/design/commandpatterndemo.asp
aqui um exemplo do uso do command exatamente como o meu, com a excessao de q nao uso undo/redo.
So q adoraria fugir disso por meio de reflection ou delegate ou qqr outra coisa q me dispensasse de criar 758.632 classes command. Mas a cabeca nao ta funcionando bem hehehe, e nao consegui formular nada sem POG pattern “else forever”.
De qqr maneira, valeu pela forca, Paulo.
Posta um exemplo de como você está fazendo. Me parece que seus Commands são Controllers. Neste caso, sugiro que leia algo sobre MVC. Isso responderá às suas dúvidas ou criar novas.
Editado:
Se tua aplicação for desktop, faça a view observar o model. Isso elimina a necessidade de ter que retornar algo bizarro.
O que é exatamente igual? O seu também é uma calculadora? Por que se apenas a estrutura for igual, todos os meus commands também o são. Afinal, essa é uma característica dos padrões. :roll:
A idéia é ter uma classe para cada command e, dependendo da aplicação, este número pode ser bem grande. Mas 758.632 é um tanto quanto exagerado. Se ainda fossem apenas 632.955!
Posta mais exemplos dos teus commands pra gente dar uma olhada.
Sim, apenas a estrutura é igual. E os commands tbm, mas acho isso meio chato.
Um pequeno exemplo seria o seguinte:
Tenho minha classe GUI no evento Leave/focusLost do TextBox/JTextField edNomeCliente o seguinte codigo:
{
this.command = new CmdNomeCli(edNomeCli.Text);
//o command abstrato tem dois atributos protected
//String valor e Cliente cliente
this.controller.setValor(command);
}
O CmdNomeCli extends command e o execute() tem a seguinte implementacao:
{
cliente.Nome = this.valor;
//ou cliente.setNome(this.valor);
}
e o setValor do controller:
public void setValor(Command c)
{
c.Cliente = this.cliente;
c.execute();
}
Entao, ai é um command desse pra cada evento de saida de cada TextBox de cada um dos Forms q eu usar. E isso é meio pé nos uevo.
Aproveitando a deixa: eu ouco muito falar dos maleficios dos gets/sets, a teoria dos porques nao usar sets/gets eu gosto muito. Mas como eu faco isso na pratica? principalmente na interface com o usuario.
Alguem conhece algum material bom pra indicar?
Onde eu escrevi. Valeu pela forca, Paulo. Leia-se Rafael.
Talvez, você não precise alterar o modelo a cada perda de foco. Então, você teria uma redução drástica na quantidade de commands.
Talvez, você nem precise de commands deixando seu próprio listener estimular seu model.
:idea: Dê uma olhada nisso.
Neste mesmo texto, o autor faz (IMHO) mal uso de get/set. Seria mais interessante ele ter métodos raise(), lower().
[quote=YvGa] Aproveitando a deixa: eu ouco muito falar dos maleficios dos gets/sets, a teoria dos porques nao usar sets/gets eu gosto muito. Mas como eu faco isso na pratica? principalmente na interface com o usuario.
Alguem conhece algum material bom pra indicar?[/quote]
Sure: http://blog.caelum.com.br/2006/09/14/nao-aprender-oo-getters-e-setters/
Caro amigo,
Segue alguns exemplos dos meus commands:
public class CmdAdquirirFoto {
public Image execute() throws JTwainException {
...
return img;
}
public class CmdEnviarMensagemEmail {
public void execute() throws AddressException, MessagingException {
...
}
[quote=paulo.assump][code]
public class CmdAdquirirFoto {
public Image execute() throws JTwainException {
…
return img;
}
[/code]
[/quote]
O próprio exemplo do livro do GoF, é bem parecido, com a diferença que cada item no menu é uma instância de um ‘MenuItem’.
[quote=paulo.assump]Caro amigo,
Segue alguns exemplos dos meus commands:
public class CmdAdquirirFoto {
public Image execute() throws JTwainException {
...
return img;
}
public class CmdEnviarMensagemEmail {
public void execute() throws AddressException, MessagingException {
...
}
[/quote]
Paulo, nesse teu caso nao caberia um overload dos metodos execute() na classe abstrata?? Ou isso deixaria o command abstrato muito grande? Nao sei se isso adianta, mas eh uma maneira de ter uma classe abstrata para todos eles.