Паттерн Команда

Паттерн Команда – поведенческий шаблон проектирования, инкапсулирует запрос в виде объекта, делая возможной организацию клиентских объектов с другими запросами, организацию очереди или регистрацию запросов, а также, поддержку отмены операций. В объектно-ориентированном программировании шаблон проектирования Команда используется для инкапсуляции всей информации, необходимой для выполнения действия или вызова события в более позднее время. Эта информация включает в себя имя метода, объект, который является владельцем метода и значения параметров метода.

Паттерн Команда

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

Реализуем этот интерфейс классом StartEngine, который будет непосредственно управлять запуском двигателя:

В конструкторе нашей команды на старт двигателя передается объект класса двигателя(Engine), который при выполнении команды (метод execute()) запустит двигатель с помощью метода start() класса Engine:

В классе двигателя всего один метод отвечающий за его запуск.



Теперь создадим класс для пульта, с которого и будем запускать двигатель для прогрева машины:

Переменная button используется для хранения команды, в нашем случае – запуск двигателя, метод setCommand() используется для назначения команд на определенные кнопки в нашем пульте (кнопка пока у нас одна, но чуть позже мы это исправим), метод так же можно вызывать повторно для изменения поведения кнопки. Метод buttonPress() вызывается при нажатии кнопки, в теле метода вызывается метод execute() для выбранной команды.

Посмотрим, как все работает:

Вывод:
Engine start!

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

Для хранения команд мы воспользовались списочным массивом. Теперь создадим классы кондиционера и команды запуска кондиционера, они будут идентичны классам, которые мы разработали для двигателя:

Осталось модернизировать класс пульта, теперь он должен хранить информацию о двух кнопках:

Как видите изменениям подверглись все методы, в конструкторе инициализируется список для хранения команд привязанных к определенным кнопкам. Метод setCommand() теперь в качестве параметра принимает не только команду но и номер кнопки, к которой она привязывается, метод add() добавляет эту команду на соответствующую позиции в списке (номер позиции команды в списке соответствует номеру кнопки). Метод buttonPress() в качестве параметра принимает номер кнопки, по этому номеру с помощью метода get() мы получаем нужную нам команду и для нее вызываем метод execute().

Протестируем, что у нас получилось:

Вывод:
Engine start!
Condition start!

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

Site Footer