Skip to content

Instantly share code, notes, and snippets.

@RasPhilCo
Last active November 21, 2015 22:03
Show Gist options
  • Save RasPhilCo/8bcbf68b9c84bb55fb90 to your computer and use it in GitHub Desktop.
Save RasPhilCo/8bcbf68b9c84bb55fb90 to your computer and use it in GitHub Desktop.
POODR, Chp 6 Acquiring Behavior Through Inheritance, Sandi Metz
class Bicycle
attr_reader :size, :chain, :tire_size
def initialize(args={})
@size = args[:size]
@chain = args[:chain] || default_chain
@tire_size = args[:tire_size] || default_tire_size
post_initialize(args)
end
def spares
{ tire_size: tire_size,
chain: chain}.merge(local_spares)
end
def default_tire_size
raise NotImplementedError
end
def post_initialize(args)
nil
end
def local_spares
{}
end
def default_chain
'10-speed'
end
end
class RoadBike < Bicycle
attr_reader :tape_color
def post_initialize(args)
@tape_color = args[:tape_color]
end
def local_spares
{tape_color: tape_color}
end
def default_tire_size
'23'
end
end
class MountainBike < Bicycle
attr_reader :front_shock, :rear_shock
def post_initialize(args)
@front_shock = args[:front_shock]
@rear_shock = args[:rear_shock]
end
def local_spares
{rear_shock: rear_shock}
end
def default_tire_size
'2.1'
end
end
road_bike = RoadBike.new(
size: 'M',
tape_color: 'red' )
road_bike.tire_size # = > '23'
road_bike.chain # = > '10-speed'
mountain_bike = MountainBike.new(
size: 'S',
front_shock: 'Manitou',
rear_shock: 'Fox')
mountain_bike.tire_size # = > '2.1'
mountain_bike.chain # = > '10-speed'
@RasPhilCo
Copy link
Author

Notes:
  • subclasses are specializations of their superclasses (e.g. they should do everything their superclass does plus more)
    • wait until you have 3 subclasses to implement an abstract superclass, if you can
    • promote abstractions to the superclass (rather than demote concrete to subclasses)
  • "This technique of defining a basic structure in the superclass and sending messages to acquire subclass-specific contributions is known as the template method pattern."
    • superclass should implement all behavior it expects (even if just raising an error)
    • provide hooks in superclass to prevent tight coupling with super

ref: https://github.com/skmetz/poodr/blob/master/chapter_6.rb#L678

@RasPhilCo
Copy link
Author

class RecumbentBike < Bicycle
  attr_reader :flag

  def post_initialize(args)
    @flag = args[:flag]
  end

  def local_spares
    {flag: flag}
  end

  def default_chain
    '9-speed'
  end

  def default_tire_size
    '28'
  end
end

bent = RecumbentBike.new(flag: 'tall and orange')
bent.spares
# -> {:tire_size => "28",
#     :chain     => "10-speed",
#     :flag      => "tall and orange"}

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