Skip to content

Instantly share code, notes, and snippets.

@RasPhilCo
Last active November 24, 2015 17:37
Show Gist options
  • Save RasPhilCo/fc1c08bab89000fa4ebc to your computer and use it in GitHub Desktop.
Save RasPhilCo/fc1c08bab89000fa4ebc to your computer and use it in GitHub Desktop.
POODR, Chp 8 Combining Objects with Composition, Sandi Metz
class Bicycle
attr_reader :size, :parts
def initialize(args={})
@size = args[:size]
@parts = args[:parts]
end
def spares
parts.spares
end
end
require 'forwardable'
class Parts
extend Forwardable
def_delegators :@parts, :size, :each
include Enumerable
def initialize(parts)
@parts = parts
end
def spares
select {|part| part.needs_spare}
end
end
require 'ostruct'
module PartsFactory
def self.build(config, parts_class = Parts)
parts_class.new(
config.collect {|part_config|
create_part(part_config)})
end
def self.create_part(part_config)
OpenStruct.new(
name: part_config[0],
description: part_config[1],
needs_spare: part_config.fetch(2, true))
end
end
road_config =
[['chain', '10-speed'],
['tire_size', '23'],
['tape_color', 'red']]
mountain_config =
[['chain', '10-speed'],
['tire_size', '2.1'],
['front_shock', 'Manitou', false],
['rear_shock', 'Fox']]
road_bike =
Bicycle.new(
size: 'L',
parts: PartsFactory.build(road_config))
road_bike.spares
# -> [#<OpenStruct name="chain", etc ...
mountain_bike =
Bicycle.new(
size: 'L',
parts: PartsFactory.build(mountain_config))
mountain_bike.spares
# -> [#<OpenStruct name="chain", etc ...
@RasPhilCo
Copy link
Author

recumbent_config =
  [['chain',        '9-speed'],
   ['tire_size',    '28'],
   ['flag',         'tall and orange']]

recumbent_bike =
  Bicycle.new(
    size: 'L',
    parts: PartsFactory.build(recumbent_config))

recumbent_bike.spares
# -> [#<OpenStruct
#       name="chain",
#       description="9-speed",
#       needs_spare=true>,
#     #<OpenStruct
#       name="tire_size",
#       description="28",
#       needs_spare=true>,
#     #<OpenStruct
#       name="flag",
#       description="tall and orange",
#       needs_spare=true>]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment