Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcelorxaviers/b18620500660980b6bb651d18c250f03 to your computer and use it in GitHub Desktop.
Save marcelorxaviers/b18620500660980b6bb651d18c250f03 to your computer and use it in GitHub Desktop.
# frozen_string_literal: true
# The command pattern is useful in situations where you want to decouple the requester of an action
# from the object that performs the action, need to support undo/redo functionality, require
# flexibility to dynamically change or extend commands, or aim to encapsulate requests as objects
# for easier management and organization in a software system.
# This pattern can be split in three main components: The receiver, the invoker and the command
# Receiver
class Television
def turn_on
puts "#{self.class.name} turned on"
end
def change_channel
puts "#{self.class.name} channel changed"
end
end
# Command "Interface"
class Command
def initialize(receiver)
@receiver = receiver
end
def execute
raise NotImplementedError, 'This is an Abstract class - Subclasses must implement this method'
end
end
# Command used to turn on a receiver. It can be used with different receivers, such as a television
# or a light, for example
class TurnOnCommand < Command
def execute
@receiver.turn_on
end
end
# Command used to turn off a receiver. It can be used with different receivers, such as a television
# or a light, for example
class ChangeChannelCommand < Command
def execute
@receiver.change_channel
end
end
# Invoker
class RemoteControl
def initialize
@commands = {}
end
def add_command(key, command)
@commands[key] = command
end
def press_button(key)
return @commands[key].execute if @commands.key?(key)
puts 'Command not found'
end
end
television = Television.new
turn_on_command = TurnOnCommand.new(television)
change_channel_command = ChangeChannelCommand.new(television)
remote_control = RemoteControl.new
remote_control.add_command(:turn_on, turn_on_command)
remote_control.add_command(:change_channel, change_channel_command)
remote_control.press_button(:turn_on) # Same as execute command
remote_control.press_button(:change_channel) # Same as execute command
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment