ruby 中的继承缓存模式

Inheritance caching patterns in ruby

说我有一个 parent class:

class Stat

  def val
    raise "method must be implemented by subclass"
  end

end

还有一个子class:

class MyStat < Stat

  def val
    #performs costly calculation and returns value
  end    

end

通过扩展 parent class,我希望子 class 不必担心缓存 [=30] 的 return 值=] 方法。

这里可以使用很多模式来达到这种效果,我已经尝试了几种尺寸,但 none 中的我觉得合适而且我知道这是一个已解决的问题所以感觉愚蠢地浪费时间和精力。这通常是如何处理的?

另外,我发现我可能问错了问题。也许我根本不应该使用继承,而应该使用组合。

任何和所有的想法表示赞赏。

编辑:

我采用的解决方案可以总结如下:

class Stat

  def value
    @value ||= build_value 
  end

  def build_value
    #to be implemented by subclass
  end

end

通常我使用一个简单的模式,不管是否存在继承:

class Parent
  def val
    @val ||= calculate_val
  end

  def calculate_value
    fail "Implementation missing"
  end
end

class Child < Parent
  def calculate_val
    # some expensive computation
  end
end

我总是喜欢将复杂而昂贵的逻辑包装在它自己的一个或多个不知道它们的 return 值将是 memoized 的方法中。它为您提供了更清晰的关注点分离;一种是缓存,一种是计算。

它也恰好为您提供了一种很好的覆盖逻辑的方法,而不覆盖缓存逻辑。

在上面的简单示例中,memoized 方法 val 非常多余。但是它的模式还可以让你记住接受参数的方法,或者当实际缓存不那么微不足道时,保持缓存和计算之间的职责分离:

def is_prime(n)
  @is_prime ||= {}
  @is_prime[n] ||= compute_is_prime
end

如果你想保持方法名称相同而不创建新方法来放入逻辑,那么在前面添加模块而不是使用 parent/child 继承。

module MA
  def val
    puts("module's method")
    @_val ||= super
  end
end

class CA
  def val
    puts("class's method")
    1
  end

  prepend MA
end

ca = CA.new
ca.val # will print "module's method" and "class's method". will return 1.
ca.val # will print "module's method". will return 1.