我有一个类,它的initialize方法从远程源获取数据,然后使用这些数据来设置其对象属性。
我预计这个类会被大量使用,在一个程序中可能会被使用数百次。我希望通过缓存已经实例化的对象来减少网络调用的开销,当用户再次请求实例化该对象时,我会将这些对象返回给用户。
为此,我一直在考虑覆盖这个类的新方法。它将检查缓存的对象是否可用,如果可用,则返回该引用。否则,它将为对象调用常规的新方法,该方法将像往常一样分配内存并调用initialize。
如果在类中重写new()方法,是否可以通过类似super()的方式调用原始的new方法
发布于 2013-04-18 05:04:48
是的,不带参数的super将使用传递给新方法的相同参数调用父方法。
或者,您可以通过将参数添加到super(p1, p2, ...)来选择参数。
关于您想要通过记住前面的调用来做什么,这称为"memoizing",至少有一个用于它的memoize gem,或者,您可以根据需要编写自己的and。
使用散列很容易做到这一点。使用调用new方法时使用的参数作为键,该值是您想要返回的实例。如果没有代码示例,很难想出一个适合自定义的示例,但这是一个简单的、未经测试的版本:
def initialize(*args)
@memoizer ||= {}
return @memoizer[args] if @memoizer[args]
# do what you will with the args in this initializer,
# then create a new instance for the future.
@memoizer[args] = super(args)
end这个想法是,@memoizer记住调用的“一致性”,并自动返回类似调用的结果。如果之前没有看到这组参数,它将计算并创建新实例,然后返回它。
当结果可能随着相同的输入参数集而改变时,这一点就会被打破。您不希望使用random或日期/时间值来记录数据库调用或任何内容,也不希望返回一些您无法控制的内容。尝试在这些情况下使用它将返回陈旧或错误的值,除非您设计了一个定期遍历和重新验证@memoizer值的方法。
此外,没有刷新机制,因此@memoizer只会在大小上增长,并且可能会在给定足够的不同输入值的情况下消耗所有可用空间。为了解决这个问题,您还可以设置一个时间戳,以确定何时将该值添加到@memoizer中,并定期清除超过给定生存期的条目。那么只有"live“值会保留在散列中。
有用的信息在:"Memoize Techniques in Ruby and Rails“。
发布于 2013-04-18 05:14:19
通过super或通过alias_method链
如果你的子类是超级的就更好了
检查这个:When monkey patching a method, can you call the overridden method from the new implementation?
https://stackoverflow.com/questions/16070142
复制相似问题