観測可能な状態

2006年1月5日

メソッドがオブジェクトの観測可能な状態を変更していないと言う場合、人々はどのような意味を込めているのでしょうか?

メソッドを状態を変更するものとそうでないものに分けることは非常に有用です。状態を変更しないメソッド (私はクエリと呼んでいます) は、他のメソッドとのシーケンスを心配することなく、あらゆるコンテキストで使用できます。

ここで重要なのは、それらが状態を変更しないことではなく、観測可能な状態を変更しないことです。オブジェクトの観測可能な状態とは、クエリメソッドから検出できるものです。簡単な例をいくつか挙げて説明しましょう。

最も簡単な例はキャッシュです。次のような範囲クラスを想像してみてください。

# ruby
class MyRange
  attr_reader :start, :finish
  def initialize start, finish
    @start, @finish = start, finish
    @lengthCache = nil
  end
  def length
    @lengthCache = (@finish - @start) unless @lengthCache
    return @lengthCache
  end
end

この場合、遅延初期化を使用して最初のアクセス時に充填されるlengthCache変数があります。lengthCacheに値を格納すると、オブジェクトの実際の状態が明らかに変更されます。オブジェクトの状態が外部から変わっていることを把握できないので、観測可能な状態は変わりません。

外部から把握できないというのは、lengthCacheの値が充填されているかどうかに関係なく、別のオブジェクトからMyRangeのメソッドを呼び出した場合の結果が同じになるという意味です。

通常、この効果はMyRangeのメソッドがフィールドを直接使用するのではなく、lengthメソッドを使用して範囲を取得することで得られます。キャッシュは、その変更が決して観測可能であってはならない状態の明白なケースです。遅延初期化は観測可能な状態を変更してはならないということもまた真実です。