ダックタイピングの例
参考
こういうclassとmethodがある場合
code:1-1.rb
class Trip
attr_reader :bicycles
def prepare(mechanic)
mecahnic.prepare_bicycles(bicycles)
end
..
end
prepare()の引数にあたるobjectは、prepare_bicyles()を持っていさえすれば何でも良い
ここではmechanicという名前を付けているが別にMechanic classである必要はない
code:1-2.rb
class Mechanic
def prepare_bicycles(bicycles)
...
end
..
end
ここまではまだ問題とも言えない微妙な状況mrsekut.icon
ここでのの問題点は、1-1.rbの段階で、prepareの引数は特定のMechanicclassをふわっと想定していることにある
さらにこう話は続く
このpreparer()が取りうるObjectが複数になり、その種類も複数になった場合を想定する
code:2.rb
def prepare(preparers)
prepareers.each {|preparer|
case preparer
when Mechanic
preparer.prepare_bicycles(..)
when TripCoordinator
preparer.buy_food(..)
when Driver
preparer.gas_up(..)
end
}
end
その複数種類として来るObjectたちはどれも「preparer風」のmethodを持っているが別々の名前であるため、case式で判別してから呼ぶ必要がある
こうなると、外部の3つのclassの実装を知っていることになる
だからこういうダックタイプを使って解決する
code:3.rb
def prepare(preparers)
preparers.each {|preparer|
preparer.prepare_trip(self)}
end
「pareparerはprepare_tripというmethodを持つ」というダックタイプを想定する
こういうダックタイプに対して(明示していないのに)Preparersと勝手に呼んでいる
動的型付けなので、Preparersという文言はコード上には現れない
ここに渡されうる側のclassのmethodをこの名前で定義するように変える