後々困らないクラス設計の基本 [条件分岐]


Motivation

switchif,elsif,elseを使う事によってスパゲティーコードを生み出している状況を打開したい

Replace type code with type class

タイプコード(下記の@format_typeの事)を使用する場合、条件分岐が発生する可能性が高く、その場合タイプコード毎にクラスを作成します。
※ playerはcaseでpriceはifで書いてますが、caseifが出来てきたら注意しましょうという場合で分けて記述しています。

before

よく見かけるコードですね

Music
  def initialize(params)
    @format_type = params[:format_type]
  end

  def player
    case @format_type
      when "cd"
        "cd player"
      when "mp3"
        "ipod"
      else
        raise "not exist format type"
    end
  end

  def price
    if @format_type === 'cd'
      1000
    elsif @format_type === 'mp3'
      500
    else
      raise "not exist format type"
    end
  end
end

after

まずはタイプコード毎にクラスを作ります

Cd
class Cd
  def player
    "cd player"
  end

  def price
    1000
  end
end
Mp3
class Mp3
  def player
    "ipod"
  end

  def price
    500
  end
end

タイプコード毎に対応するクラスのplaerを呼び出すのですが
呼び出し方を2種類紹介します。

with Factory method

Music
class Music
  def self.format_type_is(format_type)
    case format_type
      when "cd"
        Cd.new
      when "mp3"
        Mp3.new
      else
        raise "not exist format type"
    end
  end
end
music = Music.format_type_is("mp3")
puts music.player # => ipod

delegate

Music
class Music
  def initialize(params)
    case params[:format_type]
      when "cd"
        @media = Cd.new
      when "mp3"
        @media = Mp3.new
      else
        raise "not exist format type"
    end
  end

  def player
    @media.player
  end

  def price
    @media.price
  end
end

もっといいアイデアがあれば、随時修正していきます!