인스턴스 내에서 인스턴스 변수에 접근할때 메세지를 사용한다?

2013-12-07 10:24

Sandi Metz가 쓴 'Practical Object-Oriented Design in Ruby'에서 보면 인스턴스 내에서 인스턴스 변수에 접근할때도 메세지를 사용하라고 나와있다

예를들어, Gear.rb 파일이 다음과 같다고 하자.

require 'wheel'


class Gear
  def initialize(chain, cog, wheel=nil)
    @chain = chain
    @cog = cog
    @wheel = wheel
  end


  def gear_inches
    ratio * @wheel.diameter
  end


  def ratio
    @chain / @cog.to_f
  end
end


지금 'gear_inches'메서드에서 @wheel이라는 인스턴스 변수를 직접 접근하여 사용하고 있다. 'ratio'메서드에서는 @chain과 @cog라는 인스턴스 변수를 직접 접근하여 사용하고 있다.

하지만 저자는 다음과 같이 접근하라고 제시한다.

require 'wheel'


class Gear
  attr_reader :chain, :cog, :wheel


  def initialize(chain, cog, wheel=nil)
    @chain = chain
    @cog = cog
    @wheel = wheel
  end


  def gear_inches
    ratio * wheel.diameter
  end


  def ratio
    chain / cog.to_f
  end
end


인스턴스 내에서도 인스턴스 변수를 접근할 때 메세지를 사용하는 것이다. 왜 이렇게 해야할까? 내가 캐치하지 못한게 있나...

1개의 의견 from SLiPP

2013-12-07 11:11

나도 항상 이 부분에 의문이 든다. 왜 그럴까? 자바에서도 가능하면 메소드를 통해서 필드(인스턴스 변수)에 접근하라고 가이드한다. 하지만 나도 필드에 직접 접근한다.

메소드를 사용하라는 가장 큰 이유는 다음과 같은 경우 때문이 아닐까? 필드 데이터를 변경하는 경우가 발생할 수 있기 때문이라 생각한다.

예를 들어 필드의 값이 null이냐 null이 아니냐에 따라 다른 값을 반환해야 하는 경우가 있다면 이를 어디서 처리해야할까? 대부분의 경우 필드에 대한 메소드에서 값을 가공하는 작업을 하겠지.

프로그래밍을 개발하는 시점에는 그 필요를 느낄 수 있는 상황이 많지 않을 듯 한데, 향후 변경 가능성을 고려한다면 메소드를 통해 접근하는 것이 변경에 더 유연하게 대응할 수 있을 듯하다. 하지만 지금까지의 경험으로 봤을 때 필드를 직접 접근해서 문제가 되는 경우를 거의 경험하지 못했다. 테스트 코드만 잘 구현되어 있다면 필드에 직접 접근해도 되지 않을까라고 생각한다. 추후 변경이 발생하면 그 시점에 메소드에 접근하도록 리팩토링해도 되지 않을까?

약간 다른 질문이기는 하지만 http://slipp.net/questions/124 에도 비슷한 논의가 있으니 한번 봐라.

의견 추가하기

연관태그

← 목록으로