Pergunta

Estou trabalhando em um aplicativo WinForm .Net com a interface básica que inclui botões da barra de ferramentas, itens de menu e pressionamentos de tecla que iniciam o mesmo código subjacente.No momento, os manipuladores de eventos de cada um deles chamam um método comum para executar a função.

Pelo que li, esse tipo de ação poderia ser realizada pelo Padrão de design de comando com o benefício adicional de ativar/desativar ou marcar/desmarcar automaticamente os elementos da UI.

Tenho pesquisado na rede um bom projeto de exemplo, mas realmente não encontrei nenhum.Alguém tem um bom exemplo que possa ser compartilhado?

Foi útil?

Solução

Vamos primeiro ter certeza de que sabemos qual é o padrão Command:

O padrão de comando encapsula uma solicitação como um objeto e fornece uma interface pública conhecida.O padrão de comando garante que todo objeto receba seus próprios comandos e forneça uma dissociação entre o remetente e o destinatário.Um remetente é um objeto que chama uma operação e um receptor é um objeto que recebe a solicitação e age nele.

Aqui está um exemplo para você.Há muitas maneiras de fazer isso, mas adotarei uma abordagem baseada em interface para tornar o código mais testável para você.Não tenho certeza de qual idioma você prefere, mas estou escrevendo isso em C#.

Primeiro, crie uma interface que descreva um comando.

public interface ICommand
{
    void Execute();
}

Segundo, crie objetos de comando que implementarão a interface de comando.

public class CutCommand : ICommand
{
    public void Execute()
    {
        // Put code you like to execute when the CutCommand.Execute method is called.
    }
}

Terceiro, precisamos configurar nosso invocador ou objeto remetente.

public class TextOperations
{
    public void Invoke(ICommand command)
    {
        command.Execute();
    }
}

Quarto, crie o objeto cliente que usará o objeto invocador/remetente.

public class Client
{
    static void Main()
    {
        TextOperations textOperations = new TextOperations();
        textOperation.Invoke(new CutCommand());
    }
}

Espero que você possa pegar este exemplo e colocá-lo em uso no aplicativo em que está trabalhando.Se desejar mais esclarecimentos, é só me avisar.

Outras dicas

Você está no caminho certo.Basicamente você terá um modelo que representa o documento.Você usará este modelo no CutCommand.Você desejará alterar o construtor do CutCommand para aceitar as informações que deseja cortar.Então, toda vez que, digamos, o botão Cut for clicado, você invoca um novo CutCommand e passa os argumentos no construtor.Em seguida, use esses argumentos na classe quando o método Execute for chamado.

Experimente editores .NET de código aberto como SharpDevelop ou Bloco de notas++.

Há (naturalmente) alguma discussão sobre o Padrão de Comando em http://c2.com/cgi/wiki?CommandPattern isso pode ser útil.

Qt usa padrão de comando para itens da barra de menu/barra de ferramentas.

QActions são criados separadamente de QMenuItem e QToolbar, e as ações podem ser atribuídas a QMenuItem e QToolbar com os métodos setAction() e addAction() respectivamente.

http://web.archive.org/web/20100801023349/http://cartan.cas.suffolk.edu/oopdocbook/html/menus.html

http://web.archive.org/web/20100729211835/http://cartan.cas.suffolk.edu/oopdocbook/html/actions.html

Não posso ajudá-lo com o link de exemplo, mas posso fornecer um exemplo sozinho.

1) Defina a interface ICommand:

public interface ICommand {
   void Do();
   void Undo();
}

2) Faça suas implementações de ICommand para comandos concretos, mas também defina uma classe base abstrata para eles:

public abstract class WinFormCommand : ICommand {

}

3) Crie um invocador de comando:

public interface ICommandInvoker {
  void Invoke(ICommand command);
  void ReDo();
  void UnDo();
}

public interface ICommandDirector {
  void Enable(ICommand);
  void Disable(ICommand);
}

public class WinFormsCommandInvoker : ICommandInvoker, ICommandDirector {

    private readonly Dictionary<ICommand, bool> _commands;
    private readonly Queue<ICommand> _commandsQueue;       
    private readonly IButtonDirector _buttonDirector;

    // you can define additional queue for support of ReDo operation

    public WinFormsCommandInvoker(ICommandsBuilder builder, IButtonDirector buttonDirector) {
      _commands = builder.Build();
      _buttonDirector = buttonDirector;
      _commandsQueue = new Queue<ICommand>();
    } 

    public void Invoke(ICommand command) {
        command.Do();
        __commandsQueue.Enqueue(command);
    }

    public void ReDo() {
      //you can implement this using additional queue
    }

    public void UnDo() {
      var command = __commandsQueue.Dequeue();
      command.Undo();
    }

    public void Enable(ICommand command) {
      _commands.[command] = true;
      _buttonDirector.Enable(command);
    }

    public void Disable(ICommand command) {
      _commands.[command] = false;
      _buttonDirector.Disable(command); 
    }
}

4) Agora você pode implementar seu ICommandsBuilder, IButtonDirector e adicionar outras interfaces como ICheckBoxDirector ao WinFormsCommandInvoker.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top