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/0ba0b2fa87a05076c2f20fc95a798351 to your computer and use it in GitHub Desktop.
Save marcelorxaviers/0ba0b2fa87a05076c2f20fc95a798351 to your computer and use it in GitHub Desktop.
# frozen_string_literal: true
require 'ostruct'
# Command "Interface"
class Command
attr_accessor :errors, :input, :output
def initialize(**input)
@errors = []
@output = nil
@input = OpenStruct.new(**input)
end
def execute
raise NotImplementedError, "#{self.class} lacks '#{__method__}' method implementation"
end
def errors?
@errors.any?
end
end
# Receiver
class Chef
def cook(order)
raise 'we are running out of fishes' if order.to_s.casecmp('fish').zero?
"Here's your #{order}"
end
end
# Command used to cook fish
class CookFishCommand < Command
def initialize(receiver)
@receiver = receiver
super(order: 'fish')
end
def execute
@output = @receiver.cook(input.order)
rescue StandardError => e
errors << e
end
end
# Command used to cook meat
class CookMeatCommand < Command
def initialize(receiver)
@receiver = receiver
super(order: 'meat')
end
def execute
@output = @receiver.cook(input.order)
end
end
# Invoker
class Waiter
def initialize
@chef = Chef.new
@menu = {
fish: CookFishCommand,
meat: CookMeatCommand
}
end
def take_order(key)
command_class = @menu[key]
return "We don't have #{key} in our menu" if command_class.nil?
command = command_class.new(@chef)
command.execute
# Here we deal with errors
return "Sorry sir, but #{command.errors.join(', ')}" if command.errors?
command.output
end
end
waiter = Waiter.new
waiter.take_order(:meat) # Same as execute command
waiter.take_order(:fish) # Same as execute command
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment