可观察状态
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 显然会改变对象的真实状态。它不会改变可观察状态,因为你无法从外部判断对象的 state 发生了变化。
从外部无法判断是指,从另一个对象调用 MyRange 上的任何方法的结果,无论 lengthCache 值是否已填充,都将相同。
通常,你可以通过确保 MyRange 上的任何方法都使用 length 方法来获取范围,而不是直接使用字段来获得这种效果。缓存是状态更改永远不应该被观察到的一个明显案例。任何延迟初始化也不应该改变可观察状态也是真的。