デザインパターン-Adapter

Adapterパターンとは

Adapterパターンは、インタフェースに互換性の無いクラス同士を組み合わせることを目的としたパターンです。

異なるインターフェースを持つクラス間において、Adapterを間に入れることによってクラス間をつなげる役割を担います。

これにより、ある任意の機能のインタフェースを変更することなく、他クラスが提供している新しい機能を使用できるようになります。


簡単にいえば、「すでに用意されているもの」を「利用できる形」にするためのデザインパターンだといえます。

例えば、電化製品におけるACアダプターは、交流電力という「用意されたもの」をそれぞれの機器に合わせた形式の電力を「利用できる」ように変換します。

ACアダプターのように、一般化されているものを個別ケースに適合化する役割を果たすのがAdapterデザインパターンです。

なお、adapterとは「適合させるもの」という意味です。


構成要素

  • Client(利用者)
    • Targetのメソッドを利用して処理を行います。
  • Target(対象)
    • 要求されているメソッド(インタフェース)を定めます。
  • Adaptee(適合される側)
    • 既存のメソッドを提供します。
    • このメソッドの機能を「Target」のインタフェースに適合させ利用します。
  • Adapter(適合させる)
    • Adapteeのメソッドのインタフェースを吸収し、「Target」から利用できるインタフェースに変換します。

adapterパターンには、継承(is a 関係)を利用した方法と委譲(has a 関係)を利用した方法の2つの実装方法があります。


rubyによるAdapterパターン

継承を利用したAdapterパターン


#!/usr/bin/env ruby
#
# Adapter_inherit.rb
#

# 提供されている既存機能。
class Adaptee
  def initialize(string)
    @string = string
  end

  def show_with_aster
    puts "*#{@string}*"
  end
end

# 必要な機能であり、現状実装したいクラス。
class Target
  def initialize(obj)
    @obj = obj
  end

  def print
    @obj.print
  end
end

# 提供されている機能を必要な機能に変換する。
class Adapter < Adaptee
  def initialize(string)
    super(string)
  end

  def print
    show_with_aster
  end
end

# Targetを利用するクラス
class Client
  def exec(string)
    p = Target.new(Adapter.new(string))
    p.print
  end
end

Client.new.exec("message")

委譲を利用したAdapterパターン


#!/usr/bin/env ruby
#
# Adapter_delegate.rb
#

# 提供されている既存機能。
class Adaptee
  def initialize(string)
    @string = string
  end

  def show_with_aster
    puts "*#{@string}*"
  end
end

# 必要な機能であり、現状実装したいクラス。
class Target
  def initialize(obj)
    @obj = obj
  end

  def print
    @obj.print
  end
end

# 提供されている機能を必要な機能に変換する。
class Adapter
  def initialize(string)
    @obj = Adaptee.new(string)
  end

  def print
    @obj.show_with_aster
  end
end

# Targetを利用するクラス
class Client
  def exec(message)
    p = Target.new(Adapter.new(message))
    p.print
  end
end

Client.new.exec("message")

関連ページ