假设我有一个父类:
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.