第9章 ギャップを埋める: Adapter
Ruby
Published: 2019-06-26

「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)

まとめ

繰り返しますが、コードはパターンにとってそれほど重要ではないということを覚えておいてください。意図が重要です。不適切なインターフェースを持つオブジェクトに困っていて、不適切なインターフェースを扱う痛みがシステム中に広がることを防ぎたい場合に限り、アダプタを選んでください。