Как разработать шаблон команды с другим слушателем? - PullRequest
3 голосов
/ 18 ноября 2009

У меня есть окно, которое работает как дизайнер Visual Studio. Каждый документ имеет два вида:

  • Исходный вид,
  • Дизайнерский вид.

У меня есть панель инструментов, которая может выдавать разные команды. Кнопка на панели инструментов имеет строковое свойство CommandId, в котором хранится идентификатор команды, например:

  • Вырезать, Копировать, Вставить;
  • Вставить сетку,
  • Автоформат
  • ...

У меня возникают проблемы при разработке шаблона команды, в котором выполнение команды различается в зависимости от вида.

В качестве очевидного примера, Команда копирования скопирует выделенный текст в Вид источника , но скопирует выбранный элемент управления в Вид конструктора .

В настоящее время я сопоставляю строку commandId с объектом CopyCommand , но, поскольку выполнение команды отличается в зависимости от представления, я не уверен, как это должно быть реализовано .

  • Если каждое представление предоставляет список конкретной команды, которую он понимает (и, следовательно, имеет два CopyCommand подобно SourceCopyCommand и DesignCopyCommand , которые совместно используют одну и ту же команду ID)?

  • Или каждая команда должна быть уникальной, но представление имеет большую функцию отображения, которая меняет поведение в зависимости от идентификатора команды?

Ответы [ 2 ]

2 голосов
/ 21 ноября 2009

Используйте комбинацию паттерна стратегии и паттерна состояний . Сделайте так, чтобы каждое окно реализовывало интерфейс, который определяет общие команды, которые могут быть отправлены ему, например. IWindowEditCommands. Для многоканальных окон используйте объекты внутренней стратегии, чтобы инкапсулировать различную реализацию общих команд для каждого возможного состояния окна. Шаблон State появляется, когда вы переключаетесь между состояниями окна - например, вид дизайна и вид источника. Когда окно меняет состояние, оно соответствующим образом меняет тип объекта, сохраненного в commandState, гарантируя, что для реализации вырезания, копирования и вставки используется правильная конкретная стратегия.

Чтобы подключить это к объектам команд вашего меню, просто используйте меню Команды, чтобы найти текущее выбранное окно и отправить ему соответствующее сообщение.

public interface IWindowEditCommands
{
    string Copy();
    string Cut();
    void   Paste(string buffer);
}

public class Editor implements IWindowEditCommands
{
    private IWindowEditCommands commandState;

    //constructor and other methods

    public void SwitchToSourceView()
    {
        //do stuff
        commandState = new EditorSourceViewStrategy(this);
    }

    public void SwitchToDesignView()
    {
        //do stuff
        commandState = new EditorDesignViewStrategy(this);
    }

    //IWindowEditCommands methods
    public string Copy() { return commandState.Copy(); }
    public string Cut()  { return commandState.Cut(); }

    public void Paste(string buffer) { commandState.paste(buffer); }

}

public class EditorSourceViewStrategy implements IWindowEditCommands
{
    private Editor editor;

    public EditorSourceViewEditCommands(Editor editor)
    {
        this.editor = editor;
    }

    public string Copy() {return...} //return the selected source from the source view
    public string Cut()  {return...} //return the and delete the selected source from the source view
    public void Paste(String buffer) {} //insert the buffer text at the insertion point
}

public class EditorDesignViewStrategy implements IWindowEditCommands
{
    private Editor editor;

    public EditorDesignViewEditCommands(Editor editor)
    {
        this.editor = editor;
    }

    public string Copy() {return...} //return the selected TAGS from the source view
    public string Cut()  {return...} //return the and delete the selected TAGS from the source view
    public void Paste(String buffer) {} //insert the buffer text at the insertion point
}
0 голосов
/ 18 ноября 2009

Что, если передать в ICommandContext (будет похоже на Receiver, см. «Шаблоны проектирования», стр. 234). Каждое из ваших представлений будет реализовывать этот интерфейс, а затем обладать знаниями о том, как выполнить команду. Единственная ответственность объектов Command на этом этапе заключается в том, чтобы инкапсулировать действие, чтобы вы могли вызывать CopyCommand из меню, с клавиатуры «Ctrl + C», с копированием правой кнопкой мыши и, возможно, другим способом ...

public interface ICommandContext 
{
void Cut();
void Copy();
void Past();
void AutoFormat(); 
}

public SourceView : ICommandContext
{
    public void Cut()
    {
        // Do stuff here...
    }
}

public class CopyCommand : Command
{
    public override Execute(ICommandContext context)
    {
        context.Copy();
    }
}

определение (из справочная ):

Инкапсулировать запрос как объект, тем самым позволяя вам параметризовать клиенты с разными запросами, очередь или журнал запросов, и поддержка отменяется операции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...