7
votes

Comment implémenter une usine avec plusieurs commutateurs?

Je veux mettre en œuvre une fonction d'usine pour créer des objets. Mon modèle d'objet ressemble à ceci:

MyInterface* factory(char ta, char tb)
{
    if(ta == 'c' && tb == 'c')
    {
        return new MyImpl<char, char>();
    }
    if(ta == 'c' && tb == 's')
    {
        return new MyImpl<char, short>();
    }
    if(ta == 's' && tb == 'c')
    {
        return new MyImpl<short, char>();
    }
    // and so on ....
}


9 commentaires

Usine? Vous voulez dire "faux troy", comme dans la Grèce antique? Essayez-vous d'écrire un cheval de Troie?


@Dynguss: Je pense que l'exemple parle de lui-même:


Générant le code une option? Vous pouvez générer un joli interrupteur et réduire le O (n ^ 2) à une recherche O (n).


@DYNGUSS: C'est une usine, créant des objets basés sur la configuration textuelle enregistrée. Si ce n'est pas clair, vous devriez vérifier le motif de conception d'usine.


Votre code a deux erreurs qui peuvent être non liées à la question ou non. Pourriez-vous poster réel (pas pseudo-code) qui démontre votre question? Voir SSCCE.ORG pour plus d'informations.


@Kerreksb ce n'est pas moi, mais haha ​​~


@Karolyhorvath qu'est-ce que le bel interrupteur ressemblerait? Voulez-vous simplement générer le code que j'ai écrit à la main Utilisez un moteur de modèle de texte comme JINJA2 ou C MACRO?


@Kerreksb Oh, après avoir visionné une question d'histoire de la question, c'est vraiment moi ... désolé je ne suis pas bon en mer, bien que je suis sûr que c'est la typographie :-p


@Tdihp: Oui, génère le code .. Python, Ruby ... mais j'aime la solution de Kerrek, alors, nevermind :)


3 Réponses :


13
votes

Voici une idée: xxx

avec des modèles variadiques, ce modèle pourrait être étendu à n'importe quel nombre d'arguments de type - par exemple: xxx P> Utilisation: auto p = usine (std :: tuple <> (), 'c', 's', 'l');


4 commentaires

Un peu plus élégant, encore deux commutateurs, cependant.


Pourriez-vous démontrer comment? Ou dirigez-vous dans un endroit où je peux le voir? Ma familiarité avec 11 manque malheureusement pour le moment ...


@Arkadiy: Quelque chose comme Modèle usine (caractères ... TS) , puis déballer. Laissez-moi voir si je peux placer quelque chose.


@Abadiy: J'ai ajouté un exemple avec des modèles variadiques. C'est un peu brut, mais cela devrait vous donner une idée.



0
votes

Si vous pouviez vous séparer, vous pouvez vous séparer du constructeur dans NEW IPL (New InnerImpl), il est possible qu'une solution très impliquée remplace les commutateurs avec une carte:

  struct Creator {
     virtual ~Creator(){};
     virtual Interface *create(InterfaceInner *) = 0;
     virtual InterfaceInner *createInner() = 0;
  }

  std::Map<char, Creator *> creatorMap;

  template<char T>
  struct Factory {
     Factory() {
       creatorMap.insert(T, &this->creator);
    }
  }


  template<>
  struct Factory<'s'> {
    struct ShortCreator : public Creator {
     virtual Interface *create(InterfaceInner *inner) {return new Impl<short>(inner);}
     virtual InterfaceInner *createInner(return new ImplInner<short>());
    } creator;
  }




  Factory<'s'> shortFactory;
  Factory<'c'> charFactory;

  creatorMap[ta].create(creatorMap[tb].createInner());


0 commentaires

0
votes

Qu'en est-il de: xxx

Remarque: cela fonctionne bien sur Intel / AMD x86 et X64, sur la CPU avec une endansion différente (par exemple PPC), vous devez échanger TA et tb comme ceci: interrupteur (ta | tb << 8) .


1 commentaires

Je tire ton point, mais je pense qu'il y a peu de différence entre votre IPP et mon pseudodique, à l'exception de l'aspect de l'efficacité. Peut-être que vous n'avez pas eu mon problème, merci de toute façon.