Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лабы / Лабораторная_работа_по_паттернам23.docx
Скачиваний:
0
Добавлен:
11.02.2026
Размер:
1.18 Mб
Скачать

Команда (Command)

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

Объект Команда заключает в себе само действие и его параметры.

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

Паттерн Command преобразовывает запрос на выполнение действия в отдельный объект команду.

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

Команда – это объект, поэтому над ней допустимы любые операции, что и над объектом.

Интерфейс Командного объекта определяется абстрактным базовым классом Command и в самом простом случае имеет единственный метод execute().

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

Метод execute() подклассов Command просто вызывает нужную операцию получателя.

В паттерне Command может быть до трех участников:

Клиент, создающий экземпляр Командного объекта.

Инициатор запроса, использующий Командный объект.

Получатель запроса.

- Сначала Клиент создает объект ConcreteCommand, конфигурируя его получателем запроса.

- Этот объект также доступен Инициатору.

- Инициатор использует его при отправке запроса, вызывая метод execute().

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

- Паттерн Command отделяет объект, инициирующий операцию, от объекта, который знает, как ее выполнить.

- Единственное, что должен знать Инициатор, это как отправить команду.

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

Тип: поведенческий

Назначение: для обработки команды в виде объекта

Родственные шаблоны: Компоновщик, Хранитель, Прототип, Одиночка

Пример:

#include <iostream>

#include <vector>

#include <string>

using namespace std;

class Document

{

vector<string> data;

public:

void Insert( int line, const string & str )

{

if ( line <= data.size() )

data.insert( data.begin() + line, str );

else

cout << "Error!" << endl;

}

void Remove( int line )

{

if( !( line>data.size() ) )

data.erase( data.begin() + line );

else

cout << "Error!" << endl;

}

string & operator [] ( int x )

{

return data[x];

}

void Show()

{

for( int i = 0; i<data.size(); ++i )

{

cout << i + 1 << ". " << data[i] << endl;

}

}

};

class Command

{

protected:

Document * doc;

public:

virtual void Execute() = 0;

virtual void unExecute() = 0;

void setDocument( Document * _doc )

{

doc = _doc;

}

};

class InsertCommand : public Command

{

int line;

string str;

public:

InsertCommand( int _line, const string & _str ): line( _line ), str( _str ) {}

void Execute()

{

doc->Insert( line, str );

}

void unExecute()

{

doc->Remove( line );

}

};

class Receiver

{

vector<Command*> DoneCommands;

Document doc;

Command* command;

public:

void Insert( int line, string str )

{

command = new InsertCommand( line, str );

command->setDocument( &doc );

command->Execute();

DoneCommands.push_back( command );

}

void Undo()

{

if( DoneCommands.size() == 0 )

{

cout << "There is nothing to undo!" << endl;

}

else

{

command = DoneCommands.back();

DoneCommands.pop_back();

command->unExecute();

// Don't forget to delete command!!!

delete command;

}

}

void Show()

{

doc.Show();

}

};

int main()

{

char s = '1';

int line, line_b;

string str;

Receiver res;

while( s!= 'e' )

{

cout << "What to do: \n1.Add a line\n2.Undo last command" << endl;

cin >> s;

switch( s )

{

case '1':

cout << "What line to insert: ";

cin >> line;

--line;

cout << "What to insert: ";

cin >> str;

res.Insert( line, str );

break;

case '2':

res.Undo();

break;

}

cout << "$$$DOCUMENT$$$" << endl;

res.Show();

cout << "$$$DOCUMENT$$$" << endl;

}

}

  • Команда и Стратегия похожи по духу, но отличаются масштабом и применением:

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

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