Skip to content

Instantly share code, notes, and snippets.

@agarie
Created March 26, 2013 04:15
Show Gist options
  • Save agarie/5243091 to your computer and use it in GitHub Desktop.
Save agarie/5243091 to your computer and use it in GitHub Desktop.
Just a small experiment after reading "Design Patterns in Ruby", by Ross Olsen.
# Small experiment in which I try to implement the composite pattern without
# resorting to two classes.
class Composite
attr_accessor :action, :subcomposites
# Cool thing: if we don't provide a block, it'll be passed nil. So there's no
# need to make it a "default parameter" (you can't do it, actually).
def initialize(&action)
@action = action
@subcomposites = []
end
# Add another composite to this one.
def <<(subcomposite)
@subcomposites << subcomposite
end
# If this object has an action, it's a leaf.
# Else, it's a node of the tree and has a bunch of subcomposites.
def run
if @action
@action.call
else
@subcomposites.each do |s|
s.run
end
end
end
end
# Let's test it.
clean_house = Composite.new
clean_room = Composite.new
clean_room << Composite.new { puts "[room] I'm cleaning my bed!" }
clean_room << Composite.new { puts "[room] I'm cleaning my desk!" }
clean_kitchen = Composite.new
clean_kitchen << Composite.new { puts "[kitchen] I'm cleaning my knife drawer!" }
clean_kitchen << Composite.new { puts "[kitchen] I'm cleaning my spices drawer!" }
clean_fridge = Composite.new
clean_fridge << Composite.new { puts "[kitchen][fridge] Throwing away old stuff!" }
clean_fridge << Composite.new { puts "[kitchen][fridge] Organizing my bottles!" }
clean_kitchen << clean_fridge
clean_house << clean_room
clean_house << clean_kitchen
clean_house.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment