パンくず
リファクタリング-プログラマーの体質改善テクニック
オブジェクト間での特性の移動
クラスの抽出:Extract Class
内容
リファクタリング名
クラスの抽出:Extract Class
適用ケース要約
2つのクラスで行うべき仕事をしている1個のクラスがある。
適用内容要約
新しいクラスを作成し、関連フィールド、メソッドを旧クラスから新クラスに移す。
適用詳細
クラス内の処理を拡張していくにつれ、一つ以上の役割を果たすクラスになっていまい
責務があいまいになった際などにクラスの抽出が有効です。
サンプル
通常のコーディングとテストクラスのコーディングとテストの実施を実装します。
サンプルコード
▼リファクタリング前
# encoding: Shift_JIS class Coding attr_accessor:class_name,:method_list,:test_class_name,:test_method_list def initialize(class_name,method_list) @class_name=class_name @method_list=method_list @test_class_name="Test#{class_name}" @test_method_list=Array.new @method_list.each {|method| method="test#{method.capitalize}" @test_method_list.push method } end def coding() puts "#{class_name}のコーディングを開始" @method_list.each{|method| puts "#{method}メソッドのの実装完了" } puts "#{class_name}のコーディングを完了" puts "---------------------------------" end def test_coding() puts "#{test_class_name}のコーディングを開始" @test_method_list.each{|method| puts "#{method}メソッドのの実装完了" } puts "#{class_name}のコーディングを完了" puts "---------------------------------" end def test() puts "#{test_class_name}のテストを開始" @test_method_list.each{|method| puts "#{method}メソッドのテスト完了" } puts "#{test_class_name}のテストを完了" puts "---------------------------------" end end coding=Coding.new("Hoge",["method1","method2"]) coding.coding coding.test_coding coding.test
▼リファクタリング後
# encoding: Shift_JIS class Coding attr_accessor:klass,:test_class def initialize(class_name,method_list) @klass=Klass.new(class_name,method_list) test_method_list=Array.new @klass.method_list.each {|method| method="test#{method.capitalize}" test_method_list.push method } @test_class=TestClass.new("Test#{class_name}",test_method_list) end def coding() klass.coding end def test_coding() test_class.coding end def test() test_class.test end end class Klass attr_accessor:class_name,:method_list def initialize(class_name,method_list) @class_name=class_name @method_list=method_list end def coding() puts "#{class_name}のコーディングを開始" @method_list.each{|method| puts "#{method}メソッドの実装完了" } puts "#{class_name}のコーディングを完了" puts "---------------------------------" end end class TestClass < Klass def test() puts "#{class_name}のテストを開始" @method_list.each{|method| puts "#{method}メソッドのテスト完了" } puts "#{class_name}のテストを完了" puts "---------------------------------" end end coding=Coding.new("Hoge",["method1","method2"]) coding.coding coding.test_coding coding.test
▼出力結果(共通)
Hogeのコーディングを開始 method1メソッドの実装完了 method2メソッドの実装完了 Hogeのコーディングを完了 --------------------------------- TestHogeのコーディングを開始 testMethod1メソッドの実装完了 testMethod2メソッドの実装完了 TestHogeのコーディングを完了 --------------------------------- TestHogeのテストを開始 testMethod1メソッドのテスト完了 testMethod2メソッドのテスト完了 TestHogeのテストを完了 ---------------------------------
解説
コーディングを行うクラスであるCodingに
Classをあらわす情報、TestClassをあらわす情報が混在していたため
これをクラスとして抽出しました。