2010-01-29 4 views
2

Мое понимание шаблона команды состоит в том, что у вас просто есть 1 виртуальный метод «execute()», и все зависимости, которые может иметь реализация, помещаются в конструктор или через инъекцию установщика в реализацию (например, обсуждался here).Command Pattern & design design

Однако в реализации шаблона WPF я заметил, что они передают аргумент generic функции execute() (пояснил here).

Это похоже на загрязнение интерфейса для меня, что послужило бы стимулом для добавления параметра generic функции execute()?

ответ

1

Это для привязки данных. Когда вы привязываете команду к каждому объекту в списке, например, текущий экземпляр отправляется методу execute, так что вам не нужно отслеживать текущий экземпляр самостоятельно.

При этом я не думаю, что понятие командной строки WPF представляет собой реализацию шаблона команды, они просто разделяют терминологию.

1

Причиной этого параметра является изоляция между создателем команды - кто знает , что нужно команду, которая будет выполнена, и абонент - кто знает когда нужно выполнить команду.

В некоторых командах некоторая информация, необходимая для выполнения, недоступна для создателя. Вызывающий заполняет пробел, передавая параметр для выполнения. Пример. Создатель создает команду, которая фильтрует список записей в соответствии с некоторыми критериями. Список недоступен на сайте создания, так как в приложении есть много видов списков.

Вызывающий определяет, какой список необходимо отфильтровать, передав в качестве параметра.

+0

В вашем примере я бы ожидал определенного интерфейса для команд, работающих над списком, который принимает список (или интерфейс для списка) в качестве параметра, а не какой-то общий параметр. – eli

+0

@ eli.work: Я не сказал, что параметр должен быть общим. Я просто сказал, что данные, необходимые для выполнения, не всегда доступны на сайте, где создается объект команды. –

+0

. Вопрос должен быть немного яснее: это мотивировка общего параметра, о котором мне интересно. Я обновлю свой вопрос и спасибо за ответ! – eli

1

Мы используем немного измененный шаблон команды, так что в дополнение к методу Execute у нас есть два свойства Request and Response, и мы их параметризируем с использованием полиморфизма.

3

Канонический командный шаблон обычно иллюстрируется приятными автономными командами. При этом любая информация, необходимая команде, спрятана в экземпляре объекта Command (обычно через параметризованный конструктор).

Однако в некоторых случаях параметры, необходимые для выполнения, могут быть недоступны во время создания команды (известны только во время выполнения). например Представьте себе SignOutCommand(username). Имя пользователя определяется, когда пользователь нажимает кнопку SignOut после первого входа.

Таким образом, имя пользователя передается в качестве общего параметра в Command.Execute(); Каждая команда может свободно определять свой вход и выполнять соответственно, например, для произвольной команды может потребоваться 5 параметров в качестве объекта [].

+0

Я вижу, но почему бы не определить отдельный интерфейс или создать реализацию команды, которая получает имя пользователя из другого места (например, IUserNameGetter)? – eli

+0

@ eli.work Это компромисс, который я предполагаю между простотой и элегантностью. С помощью IUserNameGetter вам нужно будет создать экземпляр этого нового типа и сохранить его в объекте Command. При каждом вызове Execute объект команды снова отправит сообщение обратно, чтобы получить имя пользователя из графического интерфейса. Более болтливый, чем просто прохождение ввода. Также с ограничением WPF доступа к графическому интерфейсу из потока, который его создал, вам может потребоваться выполнить проверку и переключение потоков в вашем IUserNameGetter impl (например, если Command.Execute вызывается в рабочем потоке). – Gishu

1

Что случилось с:

public class DeleteCommand : BaseCommand 
{ 
    private Dictionary<string, object> parameters; 

    public DeleteCommand(Dictionary<string, object> parameters) 
    { 
    this.parameters = parameters; 
    } 

    public void Execute() 
    { 
    var person = (Person)parameters["Person"]; 
    var salary = System.Convert.ToDouble(parameters["Salary"]); 

    // etc. 
    } 
} 

Теперь, если у вас есть контроллер, который собирает параметры, которые вы можете передавать их через ваши команды.

+1

Я использовал аналогичный подход в тестовой автоматизации, который я написал, хотя я передаю словарь методу Execute, поэтому объекты Action могут оставаться без гражданства и поэтому кэшироваться. –