如何在ruby中将类的对象数限制为给定的数字?

时间:2010-04-03 18:59:22

标签: ruby design-patterns singleton

如何将单例模式扩展为一个类的多个对象,即如何在一个类中只有5个对象,而不是多于ruby中的对象

2 个答案:

答案 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