Vous avez besoin d'un modèle de conception pour éliminer les énumérations et instruction switch dans la création d'objets

StackOverflow https://stackoverflow.com/questions/3897221

Question

Le mot Let je suis en train de créer un jeu de sport, et dans ce jeu il y a différentes positions un joueur peut jouer, attaque, défense, etc. Je commence par la création d'une classe de base:

public abstract class Position
{
 public abstract string Name
 {
  get;
 }
}

et sous-classes ...

public class Defender : Position
{
 public override string Name
 {
  get { return "Defender"; }
 }
}

et ainsi de suite. Tout cela est bien.

Mais maintenant je besoin d'une fonction pour créer ces objets. J'ai besoin de créer par la fonction de position. Donc, une solution possible est de créer un ENUM de toutes les positions et de transmettre cette valeur à une fonction qui passe sur le ENUM et retourne l'objet approprié. Mais cela déclenche mon alarme odeur de code. Ce lien de soultion regroupe les classes, l'ENUM et l'interrupteur dans une fonction:

public static Position GetByType(Types position)
{
 switch(position)
 {
  case Types.Defender:
   return new Defender();
... and further terrible code

Quelle solution dois-je envisager? Quel modèle de conception est-ce?

Était-ce utile?

La solution

Si vous devez le faire sur une petite échelle, l'interrupteur est pas vraiment mauvais, surtout si elle vit dans un seul endroit.

Si vous devez le faire à l'échelle moyenne, vous voudrez peut-être envisager d'améliorer le fonctionnement interne un peu - la suggestion de Steve Ellinger est raisonnable. Personnellement, je préfère utiliser un IDictionary<MyEnum, Action<T>> où l'action retourne une nouvelle instance de la classe en question.

Si vous devez le faire sur une grande échelle ou configurable, vous devriez probablement vérifier un contrôleur IoC tels que StructureMap ou ninject ou quels que soient les enfants de frais jouent avec ces jours-ci.

Autres conseils

Sons comme le modèle usine .

Toutefois, il ne peut pas être une mauvaise chose d'avoir un boîtier de commutation, qui passe sur une ENUM / chaîne pour retourner le type d'objet .... tant qu'il est isolé dans un endroit .

En effet, ce que vous voulez est une usine abstraite. La facilité de mise en œuvre de l'usine dépend de la langue que vous utilisez. php permet de noms de classes variables, par exemple, de sorte que vous pouvez envoyer au nom de classe et obtenir le nouveau retour classname $. D'autres langues ne permettent pas, cependant. En fait, si votre langue ne le fait pas, vous avez déjà créé une classe d'usine!

Il n'y a pas vraiment quelque chose de plus élégant que vous pouvez faire à moins que vous voulez utiliser la réflexion pour simuler ce que php fait.

Une façon de traiter avec le commutateur est d'avoir l'usine déclarer un tableau de types et puis utilisez l'énumération comme un index dans le tableau comme ceci:

public abstract class Position {
    public abstract string Name {
        get;
    }
}
public class Defender : Position {
    public override string Name {
        get { return "Defender"; }
    }
}
public class Attacker : Position {
    public override string Name {
        get { return "Attacker"; }
    }
}
public static class PositionFactory {
    public enum Types {
        Defender, Attacker
    }
    private static Type[] sTypes = new Type[] { typeof(Defender), typeof(Attacker)};
    public static Position GetByType(Types positionType) {
        return Activator.CreateInstance(sTypes[(Int32)positionType]) as Position;
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top