Tbpgr Blog

Employee Experience Engineer tbpgr(てぃーびー) のブログ

Ruby | Collecting Inputs | Wrap collaborators in Adapter

概要

Wrap collaborators in Adapter

前提

Confident Rubyではメソッド内の処理を次のように分類しています。
・Collecting Inputs(引数チェック、変換など)
・Performing Work(主処理)
・Delivering Output(戻り値に関わる処理)
・Handling Failure(例外処理)

当記事は上記のうち、Collecting Inputsに関する話です。

詳細

状況

メソッドは共通のインターフェースを持たない様々な型のコラボレータを受け取る。
例えばロギングメソッドの出力先をファイル、ソケット、IRC等に対応するような場合。

概要

一貫したインターフェースを持つために入力をアダプタでラップする

理由

アダプタによって、特殊なケースのハンドリングを隠蔽する。
これにより、caseやif-elsif・・・などで分岐が増えていくことがなくなる。

サンプルコード仕様

数値、文字列、配列、三角形、四角形のクラスをX倍にする
メソッドを定義します。

サンプルコード(アダプタを利用しない場合)

require 'pp'

def multiply(input, count)
  case input
  when Triangle
    Triangle.new(input.width * count, input.height * count)
  when Square
    Square.new(input.width * count, input.height * count)
  else
    input*count
  end
end

class Triangle
  attr_reader :width, :height
  def initialize(width, height)
    @width, @height = width, height
  end

  def area
    @width * @height / 2.0
  end
end

class Square
  attr_reader :width, :height
  def initialize(width, height)
    @width, @height = width, height
  end

  def area
    @width * @height
  end
end

puts multiply(3, 4)
puts multiply("abc", 2)
print multiply([1,2,3], 2), "\n"
triangle = multiply(Triangle.new(2, 3), 2)
square = multiply(Square.new(2, 3), 2)
pp triangle
puts triangle.area
pp square
puts square.area

出力

12
abcabc
[1, 2, 3, 1, 2, 3]
#<Triangle:0x29495d0 @height=6, @width=4>
12.0
#<Square:0x2949570 @height=6, @width=4>
24

サンプルコード(アダプタを利用した場合)

require 'pp'

def multiply(input, count)
  input*count
end

class Triangle
  attr_reader :width, :height
  def initialize(width, height)
    @width, @height = width, height
  end

  def area
    @width * @height / 2.0
  end

  def *(other)
    @width = @width * other
    @height = @height * other
    self
  end
end

class Square
  attr_reader :width, :height
  def initialize(width, height)
    @width, @height = width, height
  end

  def area
    @width * @height
  end

  def *(other)
    @width = @width * other
    @height = @height * other
    self
  end
end

puts multiply(3, 4)
puts multiply("abc", 2)
print multiply([1,2,3], 2), "\n"
triangle = multiply(Triangle.new(2, 3), 2)
square = multiply(Square.new(2, 3), 2)
pp triangle
puts triangle.area
pp square
puts square.area

出力

12
abcabc
[1, 2, 3, 1, 2, 3]
#<Triangle:0x29495d0 @height=6, @width=4>
12.0
#<Square:0x2949570 @height=6, @width=4>
24