2009-09-15 6 views
1

Je souhaite créer un nombre d'objets inconnu. Je ne suis pas sûr s'il y a une meilleure façon de les gérer et de les référencer. Permet d'utiliser un exemple de POO standard ... disons chaque fois qu'un utilisateur entre un nom pour un animal de compagnie dans un champ de texte et clique sur un bouton qu'un nouvel objet animal de compagnie est créé via la fonction petFactory.Gestion des instances d'objet

function pet(name) 
{ 
     this.name= name; 
} 

function petFactory(textFieldInput) 
{ 
     var x = new pet(textFieldInput) 
} 

Comme il n'y a aucun moyen, que je sache (en plus d'une fonction eval), d'utiliser dynamiquement un nouveau nom de variable unique pour l'animal chaque fois petFactory est appelé, x est réaffecté à un nouvel objet et la le dernier animal de compagnie est perdu. Ce que j'ai fait est de pousser l'objet de compagnie sur un tableau dès qu'il est initialisé.

petArray.push(this); 

Donc, si je voulais l'animal nommé « mrFuzzyButtoms » je pouvais boucle à travers un tableau indexé jusqu'à ce que je trouve l'objet avec la variable d'instance « mrFuzzyButtoms »

for (n in petArray) 
{ 
     if (petarray[n].name == 'mrFuzzyBottoms') 
     { 
       // Kill mrFuzzyBottoms 
     } 
} 

ou je pourrais utiliser un tableau associatif ... peu importe ... mais le tableau est la seule méthode que je connais pour le faire. En plus d'utiliser une fonction eval pour créer des noms de variables uniques à partir de chaînes, certaines langues n'ont pas de fonction eval (actionscript3) et il y a aussi le risque de sécurité.

Y a-t-il une meilleure façon de procéder?

Édition: Actuellement, je travaille en Python, JavaScript et ActionScript.

+0

Tuer mrFuzzyBottoms? Awww. Cruauté envers les animaux! Quel mauvais! Btw, ça ressemble à C# mais ça pourrait aussi être Java. Pouvez-vous ajouter un tag de langue ou est-ce quelque chose de général pour tous les langages de programmation. –

Répondre

2

Ce que les classes de collection (listes, dictionnaires/cartes, ensembles) sont pour; pour collecter un certain nombre d'instances. Pour le cas ci-dessus, j'utiliserais probablement une carte (le nom de la classe varie selon la langue) d'un nom à l'autre.

+1

En Python, cela s'appelle un "dict", en C# c'est un Dictionary , ou Hashtable si vous ne voulez pas utiliser le type générique. – PaulMcG

+0

Dans AS3, vous devez probablement utiliser un objet plain-old, traité comme un tableau associatif (ou une classe personnalisée qui enveloppe un objet). Vous pouvez également utiliser un dictionnaire. dans votre cas, cela ne ferait aucune différence. – fenomas

+0

Dans Ruby c'est Hash, en Java c'est Map (avec sous-classes), et oui en javascript et actionscript vous avez tendance à utiliser un objet générique (vous pouvez aussi le faire en Python, mais ce n'est généralement pas recommandé). –

3

"Je pourrais utiliser un tableau associatif" Correct.

"Le tableau est la seule méthode que je connaisse pour le faire."

Renseignez-vous sur "Mappages" ou "Dictionnaires" dès que vous le pouvez. Vous constaterez qu'il fait exactement ce que vous demandez.

Quelle langue utilisez-vous? Si vous fournissez un langage spécifique, nous pouvons fournir des liens spécifiques vers la structure "Map" dans cette langue.

+0

Merci beaucoup. J'ai ajouté des tags de langue. –

0
#!/usr/bin/env python 
"""Playing with pets.  

""" 


class Pet(object): 
    """A pet with a name.""" 
    def __init__(self, name): 
     """Create a pet with a `name`. 

     """ 
     self._name = name 

    @property 
    def name(self): # name is read-only 
     return self._name 

    def __repr__(self): 
     """ 
     >>> eval(repr(self)) == self 
     """ 
     klass = self.__class__.__name__ 
     return "%s('%s')" % (klass, self.name.replace("'", r"\'")) 

    def __eq__(self, other): 
     return repr(self) == repr(other) 

    name2pet = {} # combined register of all pets 

    @classmethod 
    def get(cls, name): 
     """Return a pet with `name`. 

     Try to get the pet registered by `name` 
     otherwise register a new pet and return it 
     """ 
     register = cls.name2pet 
     try: return register[name] 
     except KeyError: 
      pet = register[name] = cls(name) # no duplicates allowed 
      Pet.name2pet.setdefault(name, []).append(pet) 
      return pet 


class Cat(Pet): 
    name2pet = {} # each class has its own registry 


class Dog(Pet): 
    name2pet = {} 


def test(): 
    assert eval(repr(Cat("Teal'c"))) == Cat("Teal'c") 

    pets = [Pet('a'), Cat('a'), Dog('a'), Cat.get('a'), Dog.get('a')] 
    assert all(pet.name == 'a' for pet in pets) 

    cat, dog = Cat.get('pet'), Dog.get('pet') 
    assert repr(cat) == "Cat('pet')" and repr(dog) == "Dog('pet')" 
    assert dog is not cat 
    assert dog != cat  
    assert cat.name == dog.name 

    assert all(v == [Cat(k), Dog(k)] 
       for k, v in Pet.name2pet.items()), Pet.name2pet 

    try: cat.name = "cat" # .name is read-only 
    except AttributeError: 
     pass 

    try: assert 0 
    except AssertionError: 
     return "OK" 
    raise AssertionError("Assertions must be enabled during the test") 


if __name__=="__main__": 
    print test() 

pet.py

+0

Merci pour l'exemple. =) Je vais devoir aller en profondeur ce soir. –