Команда — это поведенческий паттерн, позволяющий заворачивать запросы или простые операции в отдельные объекты.
Это позволяет откладывать выполнение команд, выстраивать их в очереди, а также хранить историю и делать отмену.
Сложность:
Популярность:
Применимость: Паттерн можно часто встретить в TypeScript-коде, особенно когда нужно откладывать выполнение команд, выстраивать их в очереди, а также хранить историю и делать отмену.
Признаки применения паттерна: Классы команд построены вокруг одного действия и имеют очень узкий контекст. Объекты команд часто подаются в обработчики событий элементов GUI. Практически любая реализация отмены использует принципа команд.
Концептуальный пример
Этот пример показывает структуру паттерна Команда , а именно — из каких классов он состоит, какие роли эти классы выполняют и как они взаимодействуют друг с другом.
index.ts: Пример структуры паттерна
/**
* Интерфейс Команды объявляет метод для выполнения команд.
*/
interface Command {
execute(): void;
}
/**
* Некоторые команды способны выполнять простые операции самостоятельно.
*/
class SimpleCommand implements Command {
private payload: string;
constructor(payload: string) {
this.payload = payload;
}
public execute(): void {
console.log(`SimpleCommand: See, I can do simple things like printing (${this.payload})`);
}
}
/**
* Но есть и команды, которые делегируют более сложные операции другим объектам,
* называемым «получателями».
*/
class ComplexCommand implements Command {
private receiver: Receiver;
/**
* Данные о контексте, необходимые для запуска методов получателя.
*/
private a: string;
private b: string;
/**
* Сложные команды могут принимать один или несколько объектов-получателей
* вместе с любыми данными о контексте через конструктор.
*/
constructor(receiver: Receiver, a: string, b: string) {
this.receiver = receiver;
this.a = a;
this.b = b;
}
/**
* Команды могут делегировать выполнение любым методам получателя.
*/
public execute(): void {
console.log('ComplexCommand: Complex stuff should be done by a receiver object.');
this.receiver.doSomething(this.a);
this.receiver.doSomethingElse(this.b);
}
}
/**
* Классы Получателей содержат некую важную бизнес-логику. Они умеют выполнять
* все виды операций, связанных с выполнением запроса. Фактически, любой класс
* может выступать Получателем.
*/
class Receiver {
public doSomething(a: string): void {
console.log(`Receiver: Working on (${a}.)`);
}
public doSomethingElse(b: string): void {
console.log(`Receiver: Also working on (${b}.)`);
}
}
/**
* Отправитель связан с одной или несколькими командами. Он отправляет запрос
* команде.
*/
class Invoker {
private onStart: Command;
private onFinish: Command;
/**
* Инициализация команд.
*/
public setOnStart(command: Command): void {
this.onStart = command;
}
public setOnFinish(command: Command): void {
this.onFinish = command;
}
/**
* Отправитель не зависит от классов конкретных команд и получателей.
* Отправитель передаёт запрос получателю косвенно, выполняя команду.
*/
public doSomethingImportant(): void {
console.log('Invoker: Does anybody want something done before I begin?');
if (this.isCommand(this.onStart)) {
this.onStart.execute();
}
console.log('Invoker: ...doing something really important...');
console.log('Invoker: Does anybody want something done after I finish?');
if (this.isCommand(this.onFinish)) {
this.onFinish.execute();
}
}
private isCommand(object): object is Command {
return object.execute !== undefined;
}
}
/**
* Клиентский код может параметризовать отправителя любыми командами.
*/
const invoker = new Invoker();
invoker.setOnStart(new SimpleCommand('Say Hi!'));
const receiver = new Receiver();
invoker.setOnFinish(new ComplexCommand(receiver, 'Send email', 'Save report'));
invoker.doSomethingImportant();
Output.txt: Результат выполнения
Invoker: Does anybody want something done before I begin?
SimpleCommand: See, I can do simple things like printing (Say Hi!)
Invoker: ...doing something really important...
Invoker: Does anybody want something done after I finish?
ComplexCommand: Complex stuff should be done by a receiver object.
Receiver: Working on (Send email.)
Receiver: Also working on (Save report.)
Команда на других языках программирования