Tbpgr Blog

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

書籍 リファクタリング−プログラマーの体質改善 | データの再編成 | フィールドによるサブクラスの置き換え

パンくず

リファクタリング-プログラマーの体質改善テクニック
データの再編成
フィールドによるサブクラスの置き換え

内容

リファクタリング

フィールドによるサブクラスの置き換え

適用ケース要約

定数を返すメソッド以外に違いのないサブクラスがある

適用内容要約

メソッドスーパークラスのフィールドに変えて、サブクラスを取り除く

適用詳細

機能や振舞を追加していないサブクラスは本来の意図と異なるため
スーパークラスに一本化するほうが好ましい。

サンプル

※サンプルの要件は「State/Strategyによるタイプコードの置き換え」と同じです。

時刻によって値段が変わる定食屋さんを実装します
12時台、13時台はランチ料金で2割引き。
22時から24時は深夜料金で2割増し。
その他は通常料金とします。

サンプルコード

リファクタリング

# encoding: Shift_JIS

class Diner
  def get_price(base_price)
    return DinerPriceCalculator.get_instance.calculate_price(base_price)
  end
end

class DinerPriceCalculator
  DEFAULT_PRICE_RATE = 1.0
  def self.get_instance()
    case Time.new.hour
    when 12..13
      return LunchDinerPriceCalculator.new
    when 22..24
      return NightDinerPriceCalculator.new
    else
      return self.allocate
    end
  end
  
  def get_rate()
    return  DEFAULT_PRICE_RATE
  end
  
  def calculate_price(base_price)
    base_price*get_rate()
  end
end

class LunchDinerPriceCalculator < DinerPriceCalculator
  LUNCH_TIME_PRICE_RATE = 0.8
  def get_rate()
    return LUNCH_TIME_PRICE_RATE
  end
end

class NightDinerPriceCalculator < DinerPriceCalculator
  NIGHT_TIME_PRICE_RATE = 1.2
  def get_rate()
    return NIGHT_TIME_PRICE_RATE
  end
end

diner = Diner.new
base_price=1000
puts diner.get_price(base_price)

リファクタリング

# encoding: Shift_JIS

class Diner
  def get_price(base_price)
    return DinerPriceCalculator.calculate_price(base_price)
  end
end

class DinerPriceCalculator
  DEFAULT_PRICE_RATE = 1.0
  LUNCH_TIME_PRICE_RATE = 0.8
  NIGHT_TIME_PRICE_RATE = 1.2
  
  def self.get_rate()
    case Time.new.hour
    when 12..13
      return LUNCH_TIME_PRICE_RATE
    when 22..24
      return NIGHT_TIME_PRICE_RATE
    else
      return DEFAULT_PRICE_RATE
    end
  end
  
  def self.calculate_price(base_price)
    base_price*get_rate()
  end
end

diner = Diner.new
base_price=1000
puts diner.get_price(base_price)