102 votes

Longue liste de cas relevés en Java

Désolé je ne peux pas trouver de répondre à cette question, je suis presque certain que quelqu'un d'autre a relancé avant vous.

Mon problème est que je suis en train d'écrire certaines bibliothèques système pour exécuter les appareils embarqués. J'ai des commandes qui peuvent être envoyés à ces dispositifs sur les émissions de radio. Cela ne peut être fait que par le texte. à l'intérieur du système des bibliothèques, j'ai un fil qui gère les commandes, qui ressemble à ceci

if (value.equals("A")) { doCommandA() }
else if (value.equals("B")) { doCommandB() } 
else if etc. 

Le problème, c'est qu'il y a beaucoup de commandes, il va rapidement spirale à quelque chose hors de contrôle. C'est Horrible à regarder, douloureux pour déboguer et ahurissant de comprendre dans un délai de quelques mois.

172voto

dfa Points 54490

à l'aide de modèle de Commande:

public interface Command {
     void exec();
}

public class CommandA() implements Command {

     void exec() {
          // ... 
     }
}

// etc etc

puis construire un Map<String,Command> objet et de le remplir avec de l' Command instances:

commandMap.put("A", new CommandA());
commandMap.put("B", new CommandB());

ensuite, vous pouvez remplacer le votre si/d'autre si la chaîne avec:

commandMap.get(value).exec();

MODIFIER

vous pouvez également ajouter des commandes spéciales telles que UnknownCommand ou NullCommand, mais vous avez besoin d'un CommandMap qui s'occupe de ces cas particuliers, afin de minimiser le client vérifie.

22voto

Cory Points 37551

Il y a bien un modèle de commande , mais c’est peut-être exagéré pour ce que vous faites. N’oubliez pas de baiser.

12voto

jens Points 1006

Ma suggestion serait une sorte de combinaison légère d’enum et objet de commande. Il s’agit d’un langage recommandé par Joshua Bloch au point 30 de Effective Java.

Bien sûr, vous pouvez passer des paramètres au doCommand ou ont des types de retour.

Cette solution pourrait n’être pas vraiment valable que pour les implémentations de doCommand ne correspond pas vraiment « » au type enum, qui est - comme d’habitude lorsque vous devez faire un compromis - un peu flou.

7voto

Blessed Geek Points 6930

La mise en œuvre d'une interface comme le démontre simplement et clairement par le dfa est propre et élégant (et "officiellement" de prise en charge). Ce que le concept d'interface est destinée.

En C#, nous pourrions utiliser des délégués pour les programmeurs qui utilisent due à des pointeurs en c, mais DFA de la technique est le moyen de les utiliser.

Vous pourriez avoir un tableau trop

Command[] commands =
{
  new CommandA(), new CommandB(), new CommandC(), ...
}

Ensuite, vous pouvez exécuter une commande par index

commands[7].exec();

Plagiat dans la rédaction de DFA, mais ayant une classe de base abstraite au lieu d'une interface. Avis de la cmdKey qui seront utilisées plus tard. Par expérience, je me rends compte que souvent un équipement de commande a les sous-commandes.

abstract public class Command()
{
  abstract public byte exec(String subCmd);
  public String cmdKey;
  public String subCmd;
}

La réalisation de vos commandes ainsi,

public class CommandA
extends Command
{
  public CommandA(String subCmd)
  {
    this.cmdKey = "A";
    this.subCmd = subCmd;
  }

  public byte exec()
  {
    sendWhatever(...);
    byte status = receiveWhatever(...);
    return status;
  }
}

Vous pouvez ensuite étendre générique HashMap ou table de hachage en fournissant une paire clé-valeur sucer la fonction:

public class CommandHash<String, Command>
extends HashMap<String, Command>
(
  public CommandHash<String, Command>(Command[] commands)
  {
    this.commandSucker(Command[] commands);
  }
  public commandSucker(Command[] commands)
  {
    for(Command cmd : commands)
    {
      this.put(cmd.cmdKey, cmd);
    }
  }
}

Puis construire votre commande en magasin:

CommandHash commands =
  new CommandHash(
  {
    new CommandA("asdf"),
    new CommandA("qwerty"),
    new CommandB(null),
    new CommandC("hello dolly"),
    ...
  });

Vous pouvez maintenant envoyer des commandes objectivement

commands.get("A").exec();
commands.get(condition).exec();

7voto

JeeBee Points 11882

Avoir un enum de commandes :

Si vous avez plus de quelques commandes, Rechercher en utilisant le modèle de commande, comme a répondu ailleurs (bien que vous pouvez conserver l’enum et intégrer l’appel à la classe d’implémentation au sein de l’enum, au lieu d’utiliser une table de hachage). S’il vous plaît voir Andreas ou réponse de jens à cette question pour obtenir un exemple.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X