「Rubyによるデザインパターン」の読書メモです。
アダプタは既存のインターフェースと必要なインターフェースとの間の深い溝を橋渡しするオブジェクトです。
Adapter パターンの例
例えば、TextObject を表示する実装が既にあって、
フォーマットが異なる BritishTextObject に手を入れることができない場合にも
BritishTextObject を扱うことができます。
class Renderer
def render(text_object)
text = text_object.text
size = text_object.size_inches
color = text_object.color
p text
p size
p color
end
end
class TextObject
attr_reader :text, :size_inches, :color
def initialize(text, size_inches, color)
@text = text
@size_inches = size_inches
@color = color
end
end
class BritishTextObject
attr_reader :string, :size_mm, :colour
def initialize(string, size_mm, colour)
@string = string
@size_mm = size_mm
@colour = colour
end
end
class BritshTextObjectAdapter < TextObject
def initialize(bto)
@bto = bto
end
def text
@bto.string
end
def size_inches
@bto.size_mm / 4
end
def color
@bto.colour
end
end
t = TextObject.new('text2', 100, 'blue')
Renderer.new.render(t)
b = BritishTextObject.new('string', 300, 'green')
bto = BritshTextObjectAdapter.new(b)
Renderer.new.render(bto)
Ruby でクラス拡張するパターン
class Renderer
def render(text_object)
text = text_object.text
size = text_object.size_inches
color = text_object.color
p text
p size
p color
end
end
class TextObject
attr_reader :text, :size_inches, :color
def initialize(text, size_inches, color)
@text = text
@size_inches = size_inches
@color = color
end
end
class BritishTextObject
attr_reader :string, :size_mm, :colour
def initialize(string, size_mm, colour)
@string = string
@size_mm = size_mm
@colour = colour
end
end
# 上記 BritishTextObject は require されているつもり
# 拡張
class BritishTextObject
def text
string
end
def size_inches
size_mm / 4
end
def color
colour
end
end
t = TextObject.new('text2', 100, 'blue')
Renderer.new.render(t)
b = BritishTextObject.new('string', 300, 'green')
Renderer.new.render(b)
まとめ
繰り返しますが、コードはパターンにとってそれほど重要ではないということを覚えておいてください。意図が重要です。不適切なインターフェースを持つオブジェクトに困っていて、不適切なインターフェースを扱う痛みがシステム中に広がることを防ぎたい場合に限り、アダプタを選んでください。