2010-04-03 4 views

Répondre

1

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 
+0

Vous répétez simplement sa question. – johannes

+1

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

+0

juste un doute cela sera thread sûr? –

4

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

+0

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? –

+0

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

Questions connexes