如何将单例模式扩展为一个类的多个对象,即如何在一个类中只有5个对象,而不是多于ruby中的对象
答案 0 :(得分:4)
示例代码:
# Example class which can be instanciated at most five times
# Naive approach with Class variable
class FiveAtMost
@@instances = 0
def initialize()
if @@instances >= 5
raise "No more than five instances allowed."
else
@@instances += 1
end
p "Initialized instance #{@@instances}"
end
end
one = FiveAtMost.new
two = FiveAtMost.new
three = FiveAtMost.new
four = FiveAtMost.new
five = FiveAtMost.new
# will raise RuntimeError: No more than five instances allowed.
six = FiveAtMost.new
由于某个对象垃圾收集的时刻是不可预测的,因此您需要为该事件采取某种解决方法。也许你觉得这很有用:http://pleac.sourceforge.net/pleac_ruby/classesetc.html#AEN710
答案 1 :(得分:1)
Multiton,大小有限制。
这是一个可以包含在任何类中的Multiton模块的简单实现。它可以创建的默认对象数是5,您可以通过定义一个名为max_instances
的类方法来覆盖此限制,该类方法返回类中的数字(允许的最大实例数)。
module Multiton
MAX_INSTANCES = 5
COUNT_HOOK = :max_instances
module MultitonClassMethods
def instance
size = @instances.size
max = respond_to?(COUNT_HOOK) ? self.send(COUNT_HOOK) : MAX_INSTANCES
@instances << new if size < max
@instances[rand(size)]
end
end
def self.included(klass)
klass.class_eval {
@instances = []
}
klass.private_class_method :new
klass.extend(MultitonClassMethods)
end
end
将模块包含在类中以使其成为多圈。
# Falls back to Multiton::MAX_INSTANCES
class Person
include Multiton
end
# Overrides the number of allowed instances in max_instances
class Resource
include Multiton
def self.max_instances
58
end
end
由于对象是从此多重池中的池中随机返回的,因此您可能无法在短时间内重新获得所有对象。但是,随着更多的对象被请求,它应该是平等的。您可以通过在对象中循环而不是随机选择一个来更改Multiton
模块中的此行为。
people = []
1000.times do
people << Person.instance
end
# should print 5, but may print a smaller number
p people.uniq.size
resources = []
1000.times do
resources << Resource.instance
end
# should print 58, but may print a smaller number
p resources.uniq.size