パンくず
書籍 Patterns to Patterns
Creation
Introduce Polymorphic Creation With Factory Method
概要
Introduce Polymorphic Creation With Factory Methodのリファクタリングについて
対応方法
Factory Methodを導入し、ポリモルフィズムを実現する
利点と欠点
利点
・個別にオブジェクトを作成した場合に比べ、重複が減る。
・どこでオブジェクトの生成が行われ、どのようにオーバーライドされたのかわかりやすくなる
・Factoryによって実装されることで、クラスの型を強制する。
欠点
・Factoryの実装に不要なパラメータを無視できない
手順
1.似たメソッドをもつサブクラスかあり、個別にオブジェクト生成がされている処理を変更する。
この処理をInstantiation Methodと呼ぶことにする。
あなたはこのリファクタリングをExtract Methodで使う。
Methodに一般的な名前をつける。
2.ステップ1を似たようなMethodをもつサブクラス分繰り返す。
3.次にExtract SuperClassを適用する。
この兄弟クラスのスーパークラスはFactory Method:Creatorと呼ぶ。
4.Template Methodを適用する。
Pull Up Methodを使用する。
Instantiation Methodのために、スーパークラスに抽象メソッドを宣言する。
抽象メソッドを宣言したら、Factory Methodを実装する。
各兄弟サブクラスはFactory Method:ConcreteCreatorである。
5.1~4を繰り返す。
6.各Concrete Creatorに、似た処理があればスーパークラスに移動する
サンプル
リファクタリング前
# encoding: Windows-31J class JUnit def unit_test puts "execute JUnit Test" end end class RSpec def unit_test puts "execute RSpec" end end class Java def unit_test() puts "coding" unit_tester = JUnit.new unit_tester.unit_test end end class Ruby def unit_test() puts "coding" unit_tester = RSpec.new unit_tester.unit_test end end [Java.new, Ruby.new].each {|language| language.unit_test }
リファクタリング後
# encoding: Windows-31J class JUnit def unit_test puts "execute JUnit Test" end end class RSpec def unit_test puts "execute RSpec" end end class ProgramLanguage def get_unit_test get_unit_test end def unit_test() puts "coding" unit_tester = get_unit_test unit_tester.unit_test end end class Java < ProgramLanguage def get_unit_test JUnit.new end end class Ruby < ProgramLanguage def get_unit_test RSpec.new end end [Java.new, Ruby.new].each {|language| language.unit_test }