パンくず
リファクタリング-プログラマーの体質改善テクニック
条件式の単純化
ヌルオブジェクトの導入
内容
リファクタリング名
ヌルオブジェクトの導入
適用ケース要約
コードの中でnull(nil)値のチェックを繰り返している
適用内容要約
null(nil)値の代わりにnullオブジェクトを導入する
適用詳細
nullデータの対応ために、処理の各所でif文があるような場合に
nullオブジェクトを作成することで同じインターフェースで処理を行うことが出来ます。
サンプル
プログラマーに自分の主言語でHelloWorldしてもらうメソッドを作成します。
Javaプログラマー、Rubyプログラマー、似非プログラマーが存在します。
似非は主言語を持っていないため、リファクタリング前はnullチェックを行っています。
これを統一的に扱うため、ヌルオブジェクトを導入します。
サンプルコード
# encoding: Shift_JIS class Programmer attr_accessor:main_language HELLO_WORLD="hello world" def initialize(main_language) @main_language=main_language end def output_hello_world() if @main_language.nil? puts "no language" return end if Java === @main_language puts "System.out.println(\"#{HELLO_WORLD}\")" elsif Ruby === @main_language puts "p \"#{HELLO_WORLD}\"" else raise 'error' end end end class MainLanguage attr_accessor:name def initialize() name="" end def is_null() return false end end class Java < MainLanguage attr_accessor:name def initialize() name="Java" end end class Ruby < MainLanguage attr_accessor:name def initialize() name="Ruby" end end java_programmer = Programmer.new(Java.new) java_programmer.output_hello_world ruby_programmer = Programmer.new(Ruby.new) ruby_programmer.output_hello_world fake_programmer = Programmer.new(nil) fake_programmer.output_hello_world
# encoding: Shift_JIS class Programmer attr_accessor:main_language def initialize(main_language) @main_language=main_language end def output_hello_world() @main_language.output_hello_world end end class MainLanguage attr_accessor:name HELLO_WORLD="hello world" def initialize() name="" end def is_null() return false end def output_hello_world() puts "" end end class Java < MainLanguage attr_accessor:name def initialize() name="Java" end def output_hello_world() puts "System.out.println(\"#{HELLO_WORLD}\")" end end class Ruby < MainLanguage attr_accessor:name def initialize() name="Ruby" end def output_hello_world() puts "p \"#{HELLO_WORLD}\"" end end class FakeLanguage < MainLanguage attr_accessor:name def initialize() name="Fake" end def output_hello_world() puts "no language" end end java_programmer = Programmer.new(Java.new) java_programmer.output_hello_world ruby_programmer = Programmer.new(Ruby.new) ruby_programmer.output_hello_world fake_programmer = Programmer.new(FakeLanguage.new) fake_programmer.output_hello_world
出力(共通)
System.out.println("hello world") p "hello world" no language