Шаблон команды - Цель? - PullRequest
       6

Шаблон команды - Цель?

3 голосов
/ 02 декабря 2010

Прочитав это: http://sourcemaking.com/design_patterns/command

Я все еще не совсем понимаю, зачем нам это нужно.

Ответы [ 5 ]

14 голосов
/ 02 декабря 2010

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

Команде также легче узнать, как отменить себя (т.е. выполнитьобратная операция), чтобы в случае обработки команды ее можно было сохранить в списке и затем «отменить» в обратном порядке, чтобы восстановить состояние до выполнения команд.

Также она разъединяет отправителякоманда от получателя.Это может позволить нескольким вещам генерировать одну и ту же команду (например, пункт меню и кнопка), и они будут обрабатываться одинаково.

8 голосов
/ 02 декабря 2010

Это хороший способ инкапсулировать асинхронные операции и хранить их параметры и контекст в одном месте.

например. HTTP-запрос: вы отправляете запрос через сокет и ожидаете получения ответа. Если ваша заявка, например, веб-браузер, вы не хотите блокировать, пока запрос не будет выполнен, но двигаться дальше. Если ответ приходит, вы должны продолжить в том контексте, в котором вы остановились, например, считывание данных и размещение их в нужном месте (например, размещение загруженных данных изображения где-нибудь для последующего рендеринга). Совпадение ответа с контекстом, которому он принадлежит, может стать сложным, если у вас один большой клиентский класс, запускающий несколько асинхронных операций. Ответы могут поступать в произвольном порядке. Какой ответ принадлежит чему? Что еще нужно сделать с ответом? Как справиться с возможными ошибками? Если у вас есть эти запросы, инкапсулированные в командах, и пусть команды получают только свой собственный ответ, они будут лучше знать, как продолжить и обработать ответ. Если у вас есть последовательности запросов / ответов, также намного легче отслеживать состояние последовательности. Можно группировать команды в составные команды (составной шаблон). Клиент передает все необходимое команде и ожидает ее завершения, сообщая об успехе или ошибке.

Еще одним большим преимуществом является использование многопоточности : если все данные, необходимые для операции, инкапсулированы в объекте команды, легко переместить команду в другой поток и выполнить ее там без обычные проблемы с блокировкой, которые вы получаете, когда делитесь объектами между потоками. Создать команду, передать все, что ей нужно (скопировать, а не по ссылке), передать в другой поток, синхронизировать только при получении результата, готово.

6 голосов
/ 02 декабря 2010

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

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

1 голос
/ 02 декабря 2010

По сути, шаблон Command - это способ частично достичь «Функции как объекта» в Java (или C #).

Поскольку вы не можете просто создать функцию (или метод) и делать с ней все, что хотите, например передавать ее в качестве параметра какой-либо другой функции или сохранять ее в переменной для последующего выполнения, это обходной путь для этого :

  1. Вы заключаете некоторый код в класс (это ваш execute метод).
  2. Создать класс. Теперь этот объект у вас есть «функция как объект».
  3. Вы можете передать объект в качестве параметра, сохранить его или что-то еще.
  4. В конце концов, вы захотите вызвать метод execute.
0 голосов
/ 02 декабря 2010

Описывает решение проблемы. Главным образом, мы хотим выдавать команды и не хотим определять 30 методов для 8 классов для достижения этой цели. Используя упоминание шаблона, мы выдаем объект Command, и объект может его игнорировать или каким-либо образом воздействовать на него. Сложность объекта Command определяется реализацией, но это хороший способ сказать объектам: «Эй, сделай это».

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

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

m_Canvas.push_back(new Line(1.0f, 2.0f));
m_Canvas.push_back(new Line(3.5f, 3.1f));
m_Canvas.push_back(new Circle(2.0f, 3.0f, 1.5f));

и так далее. Предполагается, что Line и Circle получены из общего базового класса Command.

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

...