Tbpgr Blog

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

書籍 リファクタリング−プログラマーの体質改善 | データの再編成 | 観察されるデータの複製

内容

リファクタリング

観察されるデータの複製

適用ケース要約

あるGUIコントロールのみで有効なドメインデータがあり、ドメインメソッドからもアクセスする必要がある。

適用内容要約

そのデータをドメインオブジェクトにコピーして、それらを同期させるためのオブザーバを設ける。

適用詳細

MVCのようにモデルとドメインを分割するのに有効な手法。

サンプル

野球観戦を実装します。
巨人対楽天の試合があり、巨人ファンと楽天ファンが観戦しています。
巨人が勝てば巨人ファンは喜び、楽天ファンは悲しみます。
楽天が勝てば巨人ファンは悲しみ、楽天ファンは喜びます。

サンプルコード

リファクタリング

# encoding: Shift_JIS

require 'observer'

GIANTS = "巨人"
EAGLES = "楽天"

class BaseballGame
  attr_accessor:winner
  
  def set_winner(winner)
    @winner=winner
    eagles_fun(winner)
    giants_fun(winner)
  end
  
  def eagles_fun(winner)
    message = "イーグルスファンは"
    if winner == GIANTS
      message << "楽天が負けて悲しんだ"
    elsif winner == EAGLES
      message << "楽天が勝っていて喜んだ"
    end
    puts message
  end
  
  def giants_fun(winner)
    message = "ジャイアンツファンは"
    if winner == GIANTS
      message << "巨人が勝っていて喜んだ"
    elsif winner == EAGLES
      message << "巨人が負けて悲しんだ"
    end
    puts message
  end
end

baseball_game = BaseballGame.new
baseball_game.set_winner(GIANTS)
puts "--------------------------------------"
baseball_game.set_winner(EAGLES)

リファクタリング

# encoding: Shift_JIS

require 'observer'

GIANTS = "巨人"
EAGLES = "楽天"

class BaseballGame
  attr_accessor:winner
  include Observable
  
  def set_winner(winner)
    @winner=winner
    changed
    notify_observers(self)
  end
end
class GiantsFun
  def update(args)
    message = "ジャイアンツファンは"
    if args.winner == GIANTS
      message << "巨人が勝っていて喜んだ"
    elsif args.winner == EAGLES
      message << "巨人が負けて悲しんだ"
    end
    puts message
  end
end

class EaglesFun
  def update(args)
    message = "イーグルスファンは"
    if args.winner == GIANTS
      message << "楽天が負けて悲しんだ"
    elsif args.winner == EAGLES
      message << "楽天が勝っていて喜んだ"
    end
    puts message
  end
end

baseball_game = BaseballGame.new
giants_fun = GiantsFun.new
eagles_fun = EaglesFun.new
baseball_game.add_observer(giants_fun)
baseball_game.add_observer(eagles_fun)

baseball_game.set_winner(GIANTS)
puts "--------------------------------------"
baseball_game.set_winner(EAGLES)

出力(共通)

ジャイアンツファンは巨人が勝っていて喜んだ
イーグルスファンは楽天が負けて悲しんだ
--------------------------------------
ジャイアンツファンは巨人が負けて悲しんだ
イーグルスファンは楽天が勝っていて喜んだ