パンくず
書籍 Patterns to Patterns
Generalization
Form Template Method
概要
Form Template Methodのリファクタリングについて
使用する場面
サブクラスに変数となる箇所と非変数となる箇所が混ざっている場合、非変数となる箇所はサブクラスで重複している。
Template Methodでリファクタリングすることで、サブクラスの重複をスーパークラスの汎用化したアルゴリズムに移動する。
対応方法
Template Methodを適用する。
Template Methodはアルゴリズムの変数となる箇所をサブクラスで実装する。
利点と欠点
手順
1.階層に似たメソッドを見つける。
(サブクラス同士が似たような手順の処理をしている)
似たようなメソッドにCompose Methodを適用し、
各クラスでシグニチャが同じクラス(Idential Class)と異なるクラス(Unique Class)を抽出する
Unique Methodを抽象メソッドにする
2.Idential MethodにPull Up Methodを適用し、スーパークラスに移動する
3.Uniqueクラス内の似たメソッドに、Rename Methodを適用する。
各サブクラス分これを繰り返す。
4.似たメソッドが、既にサブクラスになくなった場合、
同一のシグニチャを適用するためにRename Methodを適用します。
サンプル
リファクタリング前
# encoding: Windows-31J # 原則として全ての人は起きて、通勤して、働いて、通勤して、帰宅して、 # 自由時間を過ごして就寝するとします class Tanaka def initialize(name);@name=name;end def act_day() puts "■#{@name}の一日" puts "起床" puts "通勤" puts "労働" puts "通勤" puts "帰宅" puts "本を読む" # ここだけ独自処理 puts "就寝" end end class Suzuki def initialize(name);@name=name;end def act_day() puts "■#{@name}の一日" puts "起床" puts "通勤" puts "労働" puts "通勤" puts "帰宅" puts "ゲームをする" # ここだけ独自処理 puts "就寝" end end [Tanaka.new("tanaka"), Suzuki.new("suzuki")].each {|person|person.act_day}
リファクタリング後
# encoding: Windows-31J # 原則として全ての人は起きて、通勤して、働いて、通勤して、帰宅して、 # 自由時間を過ごして就寝するとします module Person def initialize(name);@name=name;end def act_day puts "■#{@name}の一日" puts "起床" puts "通勤" puts "労働" puts "通勤" puts "帰宅" act_free puts "就寝" end end class Tanaka include Person def act_free();puts "本を読む";end end class Suzuki include Person def act_free();puts "ゲームをする";end end class Fuguta include Person end [Tanaka.new("tanaka"), Suzuki.new("suzuki")].each {|person|person.act_day}
出力
■tanakaの一日 起床 通勤 労働 通勤 帰宅 本を読む 就寝 ■suzukiの一日 起床 通勤 労働 通勤 帰宅 ゲームをする 就寝