Autumn SALE
Команда

Команда на Ruby

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

Это позволяет откладывать выполнение команд, выстраивать их в очереди, а также хранить историю и делать отмену.

Сложность:

Популярность:

Применимость: Паттерн можно часто встретить в Ruby-коде, особенно когда нужно откладывать выполнение команд, выстраивать их в очереди, а также хранить историю и делать отмену.

Признаки применения паттерна: Классы команд построены вокруг одного действия и имеют очень узкий контекст. Объекты команд часто подаются в обработчики событий элементов GUI. Практически любая реализация отмены использует принципа команд.

Концептуальный пример

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

main.rb: Пример структуры паттерна

# Интерфейс Команды объявляет метод для выполнения команд. # # @abstract class Command # @abstract def execute raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'" end end # Некоторые команды способны выполнять простые операции самостоятельно. class SimpleCommand < Command # @param [String] payload def initialize(payload) @payload = payload end def execute puts "SimpleCommand: See, I can do simple things like printing (#{@payload})" end end # Но есть и команды, которые делегируют более сложные операции другим объектам, # называемым «получателями». class ComplexCommand < Command # Сложные команды могут принимать один или несколько объектов-получателей # вместе с любыми данными о контексте через конструктор. # # @param [Receiver] receiver # @param [String] a # @param [String] b def initialize(receiver, a, b) @receiver = receiver @a = a @b = b end # Команды могут делегировать выполнение любым методам получателя. def execute print 'ComplexCommand: Complex stuff should be done by a receiver object' @receiver.do_something(@a) @receiver.do_something_else(@b) end end # Классы Получателей содержат некую важную бизнес-логику. Они умеют выполнять # все виды операций, связанных с выполнением запроса. Фактически, любой класс # может выступать Получателем. class Receiver # @param [String] a def do_something(a) print "\nReceiver: Working on (#{a}.)" end # @param [String] b def do_something_else(b) print "\nReceiver: Also working on (#{b}.)" end end # Отправитель связан с одной или несколькими командами. Он отправляет запрос # команде. class Invoker # Инициализация команд. # @param [Command] command def on_start=(command) @on_start = command end # @param [Command] command def on_finish=(command) @on_finish = command end # Отправитель не зависит от классов конкретных команд и получателей. # Отправитель передаёт запрос получателю косвенно, выполняя команду. def do_something_important puts 'Invoker: Does anybody want something done before I begin?' @on_start.execute if @on_start.is_a? Command puts 'Invoker: ...doing something really important...' puts 'Invoker: Does anybody want something done after I finish?' @on_finish.execute if @on_finish.is_a? Command end end # Клиентский код может параметризовать отправителя любыми командами. invoker = Invoker.new invoker.on_start = SimpleCommand.new('Say Hi!') receiver = Receiver.new invoker.on_finish = ComplexCommand.new(receiver, 'Send email', 'Save report') invoker.do_something_important 

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.) 

Команда на других языках программирования

Команда на C# Команда на C++ Команда на Go Команда на Java Команда на PHP Команда на Python Команда на Rust Команда на Swift Команда на TypeScript