動画
https://www.youtube.com/watch?v=9lv2lBq6x4A
後半のコードです。
確か自分で写したものだったと思う。
前半が「IFを使うと分岐が増えていく」という内容なのでIFは禁止です。
require 'pry'
# change behavior of existing methods without changing original code
class House
def recite
(1..data.length).map{|i|line(i)}.join("\n")
end
def line(number)
"Num: #{phrase(number)} "
end
def phrase(number)
parts(number).join(" ")
end
def parts(number)
data.last(number)
end
def data
%w(1 2 3 4 5 6 7 8 9 10 11 12)
end
end
class RandomHouse < House
def data
@data ||= super.shuffle
end
end
class EchoHouse < House
def parts(number)
super.zip(super).flatten
end
end
class RandomeEchoHouse1 < EchoHouse
def data
# need duplication
@data ||= super.shuffle
end
end
class RandomeEchoHouse2 < RandomHouse
def parts(number)
# need duplication
super.zip(super).flatten
end
end
class RandomeEchoHouseSack < House
# so wet....
def data
@data ||= super.shuffle
end
def parts(number)
super.zip(super).flatten
end
end
# Using inheritance as a way of sharing methods.
# Not a good practice.
# p House.new.line(6)
# p RandomHouse.new.line(6)
# p EchoHouse.new.line(6)
# p RandomeEchoHouse1.new.line(6)
# p RandomeEchoHouse2.new.line(6)
# p RandomeEchoHouseSack.new.line(6)
class CoolHouse
attr_reader :data, :formatter
DATA = %w(1 2 3 4 5 6 7 8 9 10 11 12)
def initialize(orderer: DefaultOrder.new, formatter: DefaultFormatter.new)
@data = orderer.order(DATA)
@formatter = formatter
end
def recite
(1..data.length).map{|i|line(i)}.join(" ** ")
end
def line(number)
"Num: #{phrase(number)}"
end
def phrase(number)
parts(number).join(" ")
end
def parts(number)
formatter.format(data.last(number))
end
end
# Orderer role
class DefaultOrder
def order(data)
data
end
end
class RandomOrder
def order(data)
data.shuffle
end
end
# Fomatter role
class DefaultFormatter
def format(parts)
parts
end
end
class EchoFormatter
def format(parts)
parts.zip(parts).flatten
end
end
# No strange inheritance here
p CoolHouse.new.line(6)
p CoolHouse.new(orderer: RandomOrder.new).line(6)
p CoolHouse.new(orderer: RandomOrder.new, formatter: EchoFormatter.new ).line(6)
# Also Very flexible
p CoolHouse.new(orderer: RandomOrder.new).recite
p CoolHouse.new(formatter: EchoFormatter.new).recite
p CoolHouse.new(orderer: RandomOrder.new, formatter: EchoFormatter.new).recite
## Isolate the difference, Name the concept , Define the role, Inject the players
## Nothing (like null) is something (needs to be named)