ruby中的继承缓存模式



假设我有一个父类:

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

还有一个子类:

class MyStat < Stat
  def val
    #performs costly calculation and returns value
  end    
end

通过扩展父类,我希望子类不必担心缓存"val"方法的返回值。

有很多模式可以用来达到这个效果,我已经试过几种尺寸,但没有一种对我来说合适,我知道这是一个已经解决的问题,所以浪费时间和精力感觉很傻。这种情况通常是如何处理的?

此外,我突然想到我可能问错了问题。也许我根本不应该使用继承,而应该使用组合。

感谢所有的想法。

编辑:

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

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

我总是喜欢将复杂而昂贵的逻辑封装在自己的方法中,或者不知道它们的返回值会被记忆的方法中。它能让你更清晰地分离顾虑;一种方法用于缓存,另一种方法则用于计算。

它还为您提供了一种很好的方式来覆盖逻辑,而不覆盖缓存逻辑。

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

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

如果您想保持方法名称不变,并且不创建新的方法来放入逻辑,那么请准备模块,而不是使用父/子继承。

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.

最新更新