Հրաման (նախագծման ձևանմուշ)
- Անվան այլ կիրառումների համար տե՛ս՝ Հրաման (այլ կիրառումներ)
Հրաման | |
---|---|
Տեսակ | Վարքագծային |
Նշանակություն | օբյեկտի տեսքով հրամանները մշակելու համար |
Նկարագրությունը ԳօՖի "Design Patterns" գրքում | Այո |
Հրաման (անգլ.՝ Command pattern), վարքագծային նախագծման ձևանմուշ, որն օգտագործվում է օբյեկտ կողմնորոշված ծրարգավորման մեջ գործողությունը ներկայացնելու համար։ Հրամանի օբյեկտն իր մեջ պարունակում է գործողությունն իր պարամետրերով։
Ընդհանուր հասկացողություններ
[խմբագրել | խմբագրել կոդը]- Client - հայցող
- Instance - նմուշ
- Implementation - իրականացում
- Product - արգասիք
Նպատակ
[խմբագրել | խմբագրել կոդը]Սրուկտուրայի ստեղծում, որտեղ ուղարկող և ստացող դասերը ուղիղ գծով միմյանց հետ կապված չեն։ Կազմակերպում է դասի հետադարձ կանչ, որն ներառում է ուղարկող դաս։
Նկարագրություն
[խմբագրել | խմբագրել կոդը]Վարքագծային այս ձևանմուշը հայտնի է նաև Action (գործողություն) անվանումով։
Ապահովում է հրամանի մշակումը օբյեկտի տեսքով, որը թույլ է տալիս հիշել այն և որպես պարամետր ներկայացնել դասերի մեթոդներին, ինչպես նաև վերադարձնել նրա արժեքը։
Օրինակ տպիչի գրադարանը կարող է ունենա PrintJob դաս։ Դրա համար կարելի է ստեղծել PrintJob օբյեկտ, դնել անհրաժեշտ պարամետրերը և կանչել մեթոդը, որն անմիջականորեն խնդիրը կուղարկի տպման։
Օրինակներ
[խմբագրել | խմբագրել կոդը]С++
[խմբագրել | խմբագրել կոդը]#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;
}
}
С#
[խմբագրել | խմբագրել կոդը]using System;
using System.Collections.Generic;
namespace Command
{
class MainApp
{
static void Main()
{
// Создаем пользователя.
User user = new User();
// Пусть он что-нибудь сделает.
user.Compute('+', 100);
user.Compute('-', 50);
user.Compute('*', 10);
user.Compute('/', 2);
// Отменяем 4 команды
user.Undo(4);
// Вернём 3 отменённые команды.
user.Redo(3);
// Ждем ввода пользователя и завершаемся.
Console.Read();
}
}
// "Command" : абстрактная Команда
abstract class Command
{
public abstract void Execute();
public abstract void UnExecute();
}
// "ConcreteCommand" : конкретная команда
class CalculatorCommand : Command
{
char @operator;
int operand;
Calculator calculator;
// Constructor
public CalculatorCommand(Calculator calculator,
char @operator, int operand)
{
this.calculator = calculator;
this.@operator = @operator;
this.operand = operand;
}
public char Operator
{
set{ @operator = value; }
}
public int Operand
{
set{ operand = value; }
}
public override void Execute()
{
calculator.Operation(@operator, operand);
}
public override void UnExecute()
{
calculator.Operation(Undo(@operator), operand);
}
// Private helper function : приватные вспомогательные функции
private char Undo(char @operator)
{
char undo;
switch(@operator)
{
case '+': undo = '-'; break;
case '-': undo = '+'; break;
case '*': undo = '/'; break;
case '/': undo = '*'; break;
default : undo = ' '; break;
}
return undo;
}
}
// "Receiver" : получатель
class Calculator
{
private int curr = 0;
public void Operation(char @operator, int operand)
{
switch(@operator)
{
case '+': curr += operand; break;
case '-': curr -= operand; break;
case '*': curr *= operand; break;
case '/': curr /= operand; break;
}
Console.WriteLine(
"Current value = {0,3} (following {1} {2})",
curr, @operator, operand);
}
}
// "Invoker" : вызывающий
class User
{
// Initializers
private Calculator _calculator = new Calculator();
private List<Command> _commands = new List<Command>();
private int _current = 0;
public void Redo(int levels)
{
Console.WriteLine("\n---- Redo {0} levels ", levels);
// Делаем возврат операций
for (int i = 0; i < levels; i++)
if (_current < _commands.Count)
_commands[_current++].Execute();
}
public void Undo(int levels)
{
Console.WriteLine("\n---- Undo {0} levels ", levels);
// Делаем отмену операций
for (int i = 0; i < levels; i++)
if (_current > 0)
_commands[--_current].UnExecute();
}
public void Compute(char @operator, int operand)
{
// Создаем команду операции и выполняем её
Command command = new CalculatorCommand(
_calculator, @operator, operand);
command.Execute();
if (_current < _commands.Count)
{
// если "внутри undo" мы запускаем новую операцию,
// надо обрубать список команд, следующих после текущей,
// иначе undo/redo будут некорректны
_commands.RemoveRange(_current, _commands.Count - _current);
}
// Добавляем операцию к списку отмены
_commands.Add(command);
_current++;
}
}
}
Java
[խմբագրել | խմբագրել կոդը]/*the Invoker class*/
public class Switch {
private Command flipUpCommand;
private Command flipDownCommand;
public Switch(Command flipUpCommand,Command flipDownCommand){
this.flipUpCommand=flipUpCommand;
this.flipDownCommand=flipDownCommand;
}
public void flipUp(){
flipUpCommand.execute();
}
public void flipDown(){
flipDownCommand.execute();
}
}
/*Receiver class*/
public class Light{
public Light(){ }
public void turnOn(){
System.out.println("The light is on");
}
public void turnOff(){
System.out.println("The light is off");
}
}
/*the Command interface*/
public interface Command{
void execute();
}
/*the Command for turning on the light*/
public class TurnOnLightCommand implements Command{
private Light theLight;
public TurnOnLightCommand(Light light){
this.theLight=light;
}
public void execute(){
theLight.turnOn();
}
}
/*the Command for turning off the light*/
public class TurnOffLightCommand implements Command{
private Light theLight;
public TurnOffLightCommand(Light light){
this.theLight=light;
}
public void execute(){
theLight.turnOff();
}
}
/*The test class*/
public class TestCommand{
public static void main(String[] args){
Light l=new Light();
Command switchUp=new TurnOnLightCommand(l);
Command switchDown=new TurnOffLightCommand(l);
Switch s=new Switch(switchUp,switchDown);
s.flipUp();
s.flipDown();
}
}
|
Այս հոդվածի կամ նրա բաժնի որոշակի հատվածի սկզբնական կամ ներկայիս տարբերակը վերցված է Քրիեյթիվ Քոմմոնս Նշում–Համանման տարածում 3.0 (Creative Commons BY-SA 3.0) ազատ թույլատրագրով թողարկված Հայկական սովետական հանրագիտարանից (հ․ 6, էջ 619)։ |