Uso o padrão de comando há algum tempo, mas nunca tenho muita certeza da quantidade de lógica que posso colocar no Execute
método.
Minha implementação atual do padrão de comando é semelhante a esta:
public abstract class Command
{
public static event EventHandler Completed = delegate { };
public bool Success { get; private set; }
public Exception Exception {get; private set; }
public abstract bool Execute();
protected bool OnCompleted(bool success, Exception ex = null)
{
Success = success;
Exception = ex;
Completed(this, EventArgs.Empty)
return success;
}
}
e estas são as perguntas que me faço (e pratico em meus comandos):
- É bom mostrar caixas de mensagens ou caixas de diálogo de arquivo etc.?
- É possível definir propriedades de qualquer objeto?
- Um comando pode conter lógica de negócios?
- Um comando pode modificar os controles da GUI de qualquer maneira?
- Quais comandos de camada pertencem? Visualizar ou camada de dados? Posso ter comandos nas duas camadas?
- Um comando pode fazer tudo o que anteriormente estava no
button1_Click
? - Um comando deve ser testado por unidade?
- Um comando pode ser visto como um usuário que faz uso das APIs e que cria a última camada de um aplicativo e também o último recurso para capturar exceções?
- Os comandos podem ser executados também por código (o comando chama api, o api executa e, por fim, outro API chama o comando) ou apenas o usuário pode invocá-lo e as APIs não devem saber da existência dele?
- Existe um lugar para comandos no MVC ou MVVC ou qualquer outro padrão de design com um controlador? Eles parecem ser mutuamente exclusivos. O que é preferível?
Existem vários tutoriais mostrando como implementar o padrão de comando, mas nenhum discute como aplicá-lo em um aplicativo real.
A maior parte dos benefícios dos comandos é que eles facilitam desfazer uma ação, refazer uma ação, executar uma ação em vários locais (por uma conexão de rede) ou executá-la posteriormente, e assim por diante.
Com aquilo em mente:
Provavelmente não. É difícil imaginar qualquer situação em que "desfazer" uma caixa de diálogo faça sentido, e esse é o tipo de coisa que eu prefiro colocar no código da interface do usuário.
Desde que esse objeto esteja acessível de qualquer lugar que queira executar o comando, é claro que é bom alterar suas propriedades.
Absolutamente. Isso está relacionado ao fato de seu modelo "conter" a lógica de negócios; é considerado um antipadrão ("modelo de domínio anêmico") ter muito pouca lógica de negócios.
Se os controles da GUI fazem parte do seu modelo, absolutamente. Caso contrário, é questionável.
Definitivamente não é a vista. A visualização deve ser informada de que os dados ou o modelo foram alterados e reagem de acordo, mas a mudança real deve ocorrer nos dados ou no modelo.
Em princípio, provavelmente sim. Ser capaz de desfazer comandos é uma das melhores coisas sobre o padrão.
A função execute () do comando definitivamente deve ser testada em unidade. Novamente, se os comandos estiverem vinculados a um modelo de algum tipo, eles estarão entre as partes mais fáceis de um aplicativo para teste.
Não tenho muita certeza do que você quer dizer, mas:
Absolutamente. A maioria dos benefícios dos comandos é praticamente impossível de implementar se o código nunca os executa.
Provavelmente já é óbvio agora, mas não os vejo como mutuamente exclusivos. Na minha equipe de trabalho, o controlador converte eventos gerados pelo usuário em comandos, o modelo recebe e executa os comandos (e salva os comandos "desfazer" em algum lugar) e, quando termina, o controlador diz à exibição para atualizar-se com base no novo modelo . Os comandos também são enviados pela rede para quaisquer cópias do modelo que estão sendo visualizadas por outros usuários, para que eles também o vejam. Funciona de forma brilhante.
E a pergunta do título: quanta lógica colocar em um comando? Eu não colocaria mínimo ou máximo nisso. O que eu diria é que é uma idéia muito boa implementar comandos mais complexos usando uma série de comandos mais simples e refatorar comandos da mesma maneira que você refatoraria as funções.
fonte