Вы можете переопределить Foo.new
в своем объекте и делать там что хотите:
class Foo
def self.new(id, var1, var2)
return instance if instance = self.lookup
instance = self.allocate
instance.send :initialize, var1, var2
return self.store(instance)
end
end
Вы также можете, очевидно, использовать другой метод класса для получения объекта;сделайте метод initialize
закрытым, чтобы предотвратить случайное распределение.
Таким образом, у вас будет только один экземпляр с каждым идентификатором, что, как правило, гораздо менее болезненно, чем предлагаемый вами шаблон.
Вы по-прежнемунеобходимо реализовать биты store
и lookup
, и нет ничего лучше, чем Hash
или Array
в вашем классе, чтобы сделать это с.
Вы хотите подумать о переносевещи, которые вы храните в своем классе в экземпляре WeakRef , но при этом возвращаете реальный объект.Таким образом, класс может обеспечивать уникальность, не ограничивая также, чтобы каждый когда-либо использовавшийся идентификатор оставался в памяти постоянно.
Это подходит не для каждой версии ваших обстоятельств, но, безусловно, для некоторых.Пример:
# previous code omitted ...
return store(instance)
end
def self.store(instance)
@instances ||= {}
@instances[instance.id] = WeakRef.new(instance)
instance
end
def self.lookup(id)
@instances ||= {}
if weakref = @instances[id] and weakref.weakref_alive?
return weakref.__getobj__ # the wrapped instance
else
return nil
end
end