2010-12-02 4 views
3

После прочтения этого вопроса: http://sourcemaking.com/design_patterns/commandCommand Pattern - Цель?

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

+1

Вы прочитали сайт? Используйте, если вы: `Необходимо отправлять запросы на объекты, не зная ничего о запрошенной операции или получателе запроса.` – 2010-12-02 11:58:40

ответ

6

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

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

0

В нем описывается решение проблемы. В основном, мы хотим выпустить команды и не хотим определять 30 методов для 8 классов для достижения этого. Используя упоминание шаблона, мы выдаем объект Command, и объект может игнорировать его или действовать по-другому. Сложность объекта 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.

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

14

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

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

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

1

В принципе, шаблон команды - это способ частично достичь «функции как объекта» в Java (или C#).

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

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

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

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

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

Смежные вопросы