0

我有一个类,其initialize方法从远程源获取数据,然后使用它来设置其对象属性。

我期待这个类被大量使用,可能在一个程序中被使用数百次。我想通过缓存已经实例化的对象来减少开销网络调用,然后当他们要求再次实例化该对象时我会返回给用户。

为此,我一直在考虑覆盖这个类的新方法。它将检查缓存的对象是否可用,如果可用,则返回该引用。否则,它将调用对象的常规 new 方法,该方法将分配内存并initialize像往常一样调用。

如果我重写new()类中的方法,是否可以new通过类似的方式调用原始方法super()

4

2 回答 2

3

是的,super不带参数将调用父方法,将相同的参数传递给新方法。

或者,您可以通过将参数添加到super(p1, p2, ...).

关于你想通过记住以前的调用来做什么,这被称为“记忆”,并且至少有一个记忆宝石,或者,你可以自己写,这取决于你的需要。

使用哈希很容易做到。使用调用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记住调用的“arity”并自动返回类似调用的结果。如果在计算并创建新实例然后返回它之前没有看到那组参数。

当结果可能随着相同的输入参数集发生变化时,这种情况就会崩溃。您不想记忆数据库调用或使用random日期/时间值的任何内容,或者返回您无法控制的内容。在这些情况下尝试使用它会返回陈旧或错误的值,除非您设计一种方法来@memoizer定期扫描并重新验证这些值。

此外,没有刷新机制,因此@memoizer只会增加大小,并且可能会在给定足够不同的输入值的情况下消耗所有可用空间。为了解决这个问题,您还可以为值添加到的时间设置一个时间戳@memoizer,并定期清除超过给定生命周期的条目。那时只有“实时”值会保留在散列中。

有用的信息位于:“ Ruby 和 Rails 中的记忆技术”。

于 2013-04-17T21:04:48.117 回答
1

通过super或通过alias_method

如果你是子类,超级更好

检查一下:当猴子修补方法时,你可以从新实现中调用被覆盖的方法吗?

于 2013-04-17T21:14:19.270 回答