Skip to content

Instantly share code, notes, and snippets.

@kchens
Created March 25, 2015 23:10
Show Gist options
  • Save kchens/7249eb566d4f60cdf826 to your computer and use it in GitHub Desktop.
Save kchens/7249eb566d4f60cdf826 to your computer and use it in GitHub Desktop.
POODR: Chapter 2 - Designing Classes With Single Repsonsibility
# 1 -------------------BAD
class Gear
attr_reader :chainring, :cog
def initialize(chainring, cog)
@chainring = chainring
@cog = cog
end
def ratio
chainring / cog.to_f
end
end
puts Gear.new(52, 11).ratio
puts Gear.new(30, 27).ratio
# 1 -------------------GOOD
class Gear
attr_reader :chainring, :cog, :rim, :tire
def initialize(chainring, cog, rim, tire)
@chainring = chainring
@cog = cog
@rim = rim
@tire = tire
end
def ratio
chainring / cog.to_f
end
def gear_inches
ratio * (rim + (tire * 2))
end
end
puts Gear.new(52, 11, 26, 1.5).gear_inches
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Hide Instance Variables
# 2 -------------------BAD
class Gear
def initialize(chainring, cog)
@chainring = chainring
@cog = cog
end
def ratio
@chainring / @cog.to_f
end
end
# 2 -------------------GOOD
class Gear
attr_reader :chainring, :cog
def initialize(chainring, cog)
@chainring = chainring
@cog = cog
end
def ratio
chainring / cog.to_f
end
end
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Hide Data Structures
# 3 -------------------BAD
class ObscuringReferences
attr_reader :data
def initialize(data)
@data = data
end
def diameters
data.collect do |cell|
cell[0] + (cell[1] * 2)
end
end
end
# rim and tire sizes (now in millimeters!) in a 2d array
@data = [[622, 20], [622, 23], [559, 30], [559, 40]]
# 3 -------------------GOOD
class RevealingReferences
attr_reader :wheels
def initialize(data)
@wheels = wheelify(data)
end
def diameters
wheels.collect do |wheel|
wheel.rim + (wheel.tire * 2)
end
end
Wheel = Struct.new(:rim, :tire)
def wheelify(data)
data.collect do |cell|
Wheel.new(cell[0], cell[1])
end
end
end
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Enforce Single Responsibility
# 4 -------------------GOOD
def diameters
wheels.collect { |wheel| diameter(wheel) }
end
def diameter(wheel)
wheel.rim + (wheel.tire * 2)
end
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Isolating Extra Responsibilities
# 5 -------------------OKAY
class Gear
attr_reader :chainring, :cog, :wheel
def initialize(chainring, cog, rim, tire)
@chainring = chainring
@cog = cog
@wheel = Wheel.new(rim, tire)
end
def ratio
chainring / cog.to_f
end
def gear_inches
ratio * wheel.diameter
end
# This says that wheel exists only in the context of gear.
Wheel = Struct.new(:rim, :tire) do
def diameter
rim + (tire * 2)
end
end
end
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Final Wheel
class Gear
attr_reader :chainring, :cog, :wheel
def initialize(chainring, cog, wheel=nil)
@chainring = chainring
@cog = cog
@wheel = wheel
end
def ratio
chainring / cog.to_f
end
def gear_inches
ratio * wheel.diameter
end
end
class Wheel
attr_reader :rim, :tire
def initialize(rim, tire)
@rim = rim
@tire = tire
end
def diameter
rim + (tire * 2)
end
def circumference
diameter * Math::PI
end
end
@wheel = Wheel.new(26, 1.5)
puts @wheel.circumference
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment