Null Object Refactoring

Tags:

마틴 파울러의 Refactoring에서 다뤄진 Introduce Null Object 패턴을 Ruby Metaprogramming techniques를 참고해 작성했습니다.

Ruby에서의 nil은 그 자체로 NilClass의 인스턴스입니다.

irb(main):001:0> a = nil
=> nil
irb(main):002:0> a.class
=> NilClass
irb(main):003:0> a.kind_of?(NilClass)
=> true
irb(main):004:0>

그래서 다음과 같이 NilClass를 바꿀 수 있죠.

#!/usr/bin/ruby

class Foo
    def run(cmd)
        puts "Default Action: #{cmd}"
    end
end

objs = [Foo.new, nil]

# Bad way to handle nulls
cmd = "hello world"
objs.each do |o|
    if o.nil?
        puts "NIL Object Action: #{cmd}"
    else
        o.run(cmd)
    end
end

# Better way called Null Object Refactoring
def nil.run(cmd)
    puts "NIL Object Action: #{cmd}"
end

objs.each do |o|
    o.run(cmd)
end

nil이 사용되는 곳이 많을테니 이것이 바람직한 코딩이라고 생각되지는 않습니다. 특정 범위 내에서만 NilClass를 재정의 가능하다면 쓸만하겠지만, 그 방법은 모르겠네요.

Comments

3 responses to “Null Object Refactoring”

  1. 공성식 Avatar
    공성식

    Martin Fowler의 Refactoring은 자바를 기준으로 쓴 책이다보니 루비에 적용하다보면 약간 이상해지는 경우가 있습니다.

    보여주신 코드에는 한 가지 문제점이 있습니다.
    (거의) 동일한 코드가 두 개의 메소드로 분산이 됐다는 점입니다(boilerplate code).
    (물론 이론적인 설명을 위한 것이었겠지만요…)
    루비는 자바와 달리 Duck Typing과 Mix-in이 가능하므로 그걸 최대한 이용하면 좋을 것 같습니다.

    아래와 같이 하면 코드가 한곳으로 집중되고, nil뿐 아니라 다른 클래스에서도 재활용할 수 있으므로 더 바람직할 것 같습니다.
    (단순한 예제이다 보니 코드가 더 길어졌지만 현실에선 그렇지 않습니다.)
    코드를 Generic하게 만들기 위해 @run_prefix를 customize할 수 있게 하였습니다.

    module M
    attr_writer :run_prefix
    def run(cmd)
    puts “#{@run_prefix ||= “Default”} Action: #{cmd}”
    end
    end

    class Foo
    nil.extend M
    nil.run_prefix = “Nil Class”
    include M
    end

    objs = [Foo.new, nil]
    objs.each do |o|
    o.run(“hello world”)
    end

    민구님 말씀대로, 여러 곳에서 nil에 메소드를 추가하게 되면(일종의 Monkey patch) 간혹 충돌이 날 수도 있을 것입니다.
    현재로선 범위를 지정해서 하는 방법은 없습니다.
    다만 루비 2.0에서는 이걸 Namespace 단위로 하겠다고 했으니 기다려보죠.

  2. MKSeo Avatar
    MKSeo

    하핫;;; 오.. 완전 대단한 해커신데요 -_-)b 거기에 boilerplate code라는 표현까지 ㅎㅎ 영어도 잘하시고..

    혹시 루비로 업무를 하시나요??? 평소 이렇게 까지 생각하기란 정말 힘들텐데;; 어디선 extend, 어디선 include 를 써야하는, 그리고 class_eval과 instance_eval이 헷갈리는 복잡한 언어이긴 하지만 정말 루비는 hackerish language가 아닐 수 없어요..

  3. 공성식 Avatar
    공성식

    칭찬은 감사합니다만, 사실 아직 내공이 많이 부족하답니다.
    루비를 업무에서 사용하는 것이 저의 바램입니다만, 그렇지 못합니다.
    직장에선 아주 원시적인 언어들을 사용하고 있죠…T.T

Leave a Reply

Your email address will not be published. Required fields are marked *