Comment prolonger le motif de singleton à un certain nombre d'objets à une classe à-dire comment puis-je avoir seulement cinq objets d'une classe au maximum et pas plus que dans le rubisComment limiter le nombre d'objets d'une classe à un nombre donné dans ruby?
Répondre
Multiton avec des contraintes de taille.
Voici une implémentation naïve d'un module Multiton que vous pouvez inclure dans n'importe quelle classe. Le nombre par défaut d'objets qu'il peut créer est 5, et vous pouvez remplacer cette limite en définissant une méthode de classe appelée max_instances
qui renvoie un nombre (nombre maximal d'instances autorisé) dans votre classe.
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
Inclure le module dans une classe pour en faire une multiton.
# 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
Puisque les objets sont retournés au hasard d'une piscine dans ce multiton, vous ne pouvez pas obtenir tous les objets en arrière sur un court terme. Mais comme plus d'objets sont demandés, il devrait égaliser. Vous pouvez modifier ce comportement dans le module Multiton
en parcourant les objets au lieu d'en sélectionner un au hasard.
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
code Exemple:
# 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
Depuis le moment où un objet se déchets collectés n'est pas prévisible, vous aurez besoin d'une sorte de solution de contournement pour le cet événement. Peut-être que vous trouvez cela utile: http://pleac.sourceforge.net/pleac_ruby/classesetc.html#AEN710
Je suppose que vous gardez les instances créées dans un tableau (dans la variable de classe, qui pourrait être utilisée à la place de '@@ instances' pour la limitation d'instanciation aussi bien) empêcherait la collecte des ordures? –
Oui, j'ai appelé mon approche naïve. Avec votre suggestion et un finaliseur personnalisé, cela peut être une bonne solution. Si vous aimez (et pouvez), éditez mon post, puisque je suis à court de temps en ce moment. – miku
Vous répétez simplement sa question. – johannes
merci de me montrer l'erreur de mes façons johannes. J'essayais juste de ratisser quelques points gratuits: P. permettez-moi d'ajouter plus à la réponse maintenant – Anurag
juste un doute cela sera thread sûr? –