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.
说我有一个 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.