Tbpgr Blog

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

書籍 リファクタリング−プログラマーの体質改善 | 条件式の単純化 | ヌルオブジェクトの導入

内容

リファクタリング

ヌルオブジェクトの導入

適用ケース要約

コードの中で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