可觀察狀態
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
變數,在第一次存取時使用LazyInitialization填入。將值放入lengthCache明顯會改變物件的實際狀態。它不會改變可觀察狀態,因為你無法從外部得知物件的狀態已經改變。
我所謂的無法從外部得知,是指從另一個物件呼叫任何MyRange方法的結果,無論lengthCache值是否已填入,都會相同。
通常,你可以透過確保MyRange
上的任何方法都使用length方法來取得範圍,而不是直接使用欄位,來達到這種效果。快取是一個明顯的狀態範例,其變更永遠不應該被觀察到。任何延遲初始化也不應該改變可觀察狀態,這也是正確的。