2019-05-09
Rubyによるデザインパターン - adapter
[](http://www.amazon.co.jp/exec/obidos/ASIN/4894712857/hatena- blog-22/)
利用する場面
やりとりをさせたい複数のオブジェクトの間でインターフェースが噛み合わないとき。 一方または両方のクラスのインターフェースを変更してもよいが、インターフェースを揃える役割を adapter に担わせて解決することができる。
その他
- 呼び出される側をいじることに注意する。
- 永続的に or その場限りで必要なメソッドをもたせてもよいのでは?と思ったら、まさしくその説明がでてきた。
- つまり、クラスの上書き or 特異メソッド。
- 「アダプタではいくらかの複雑さと引き換えに純化と引き換えに、内部をいじくり回すコストがかかります。」
サンプル
犬は人間の挨拶に答えられないが、adapter を使って答えられるようにしてみる。
class Creature
attr_reader :name
def initialize(name)
@name = name
end
end
class Man < Creature
def greet(man)
p "hello, #{man.name}"
man.reply(self)
end
def reply(man)
p "hello, #{man.name}"
end
end
class Dog < Creature
def bark
p "bowwow"
end
end
taro = Man.new(:taro )
jiro = Man.new(:jiro )
pochi = Dog.new(:pochi)
taro.greet(jiro) # => "hello, jiro", "hello, taro"
taro.greet(pochi) # => "hello, pochi", (NoMethodError)
class DogAdapter
attr_reader :name
def initialize(dog)
@dog = dog
@name = dog.name
end
def reply(man)
p "hello, #{man.name}"
end
end
speakable_pochi = DogAdapter.new(pochi)
taro.greet(speakable_pochi) # => "hello, pochi", "hello, taro"
特異メソッドを使って、ポチだけが話せるようにしてみる。
class << pochi
def reply(man)
p "hello, #{man.name}"
end
end
taro.greet(pochi) # => "hello, pochi", "hello, taro"
ちなみに特異メソッドは以下の書き方でも定義できる。
def pochi.reply(man)
p "hello, #{man.name}"
end
taro.greet(pochi) # => "hello, pochi", "hello, taro"