4 votes

Nettoyer le flux de contrôle lors de l'utilisation d'arguments de ligne de commande [C#].

J'ai affaire à un programme qui fait beaucoup de branchements if...else basés sur des arguments de ligne de commande. C'est en C#, mais je suis sûr que c'est applicable à Java, C++, etc. Voici les grandes lignes :

if (args.Length == 0)
{
  //do something
}

if (args.Length > 0 && args.Length < 2)
    {
        Console.WriteLine("Only one argument specified. Need two arguments");
        return 0;

    }
            else if (args.Length > 0 && args.Length >= 2)
            {
                //Process file - Argument 1
                if(args[0].Trim() == PROCESS_OPTION_ONE
                    || args[0].Trim() == PROCESS_OPTION_TWO)
                {
                    //Process file - Argument 2
                    if(args[1].Trim() == PROCESS_CUSTOMER
                        || args[1].Trim() == PROCESS_ADMIN
                        || args[1].Trim() == PROCESS_MEMBER
                        || args[1].Trim() == PROCESS_GUEST
                        || args[1].Trim() == PROCESS_USER
                        )
                    {

Comme vous pouvez le constater, c'est un peu le bazar. Existe-t-il un ou deux modèles de conception qui permettraient de faire un peu de ménage ? Un modèle de commande, peut-être ? Merci pour vos conseils et astuces.

4voto

Will Points 76760

Arrêter la nidification.

Vous pouvez changer de méthode comme l'a dit Joel (+1), ou vous pouvez simplement décomposer votre logique en appels de méthode clairs.

if(args.Length <= 1)
{
  Console.WriteLine("Need 2 args kthx");
  return;
}
if(args.Length > 2)
{
  Console.WriteLine("More than 2 args don't know what do");
  return;
}

var arg1 = args[0].Trim();
var arg2 = args[1].Trim();

switch(arg1)
{
  case PROCESS_OPTION_ONE:
     ProcessOptionOne(arg2);
     break;
  case PROCESS_OPTION_TWO:
     ProcessOptionTwo(arg2);
     break;
  default:
     Console.WriteLine("First arg unknown I give up");
     return;
}

ensuite, dans vos méthodes de traitement...

private static void ProcessOptionTwo(string argumentTwo)
{
  if(argumentTwo == PROCESS_CUSTOMER ||
     argumentTwo  == PROCESS_ADMIN ||
     /* etc blah blah */
}

Gardez vos méthodes aussi simples que possible et divisez les algorithmes longs et confus en appels de méthodes distincts qui, par leur nom, donnent une indication claire de ce qu'ils font.

3voto

Joel Etherton Points 24155

Je préfère utiliser des instructions de commutation sur le tableau d'arguments et définir des propriétés dans une classe de configuration quelconque pour chaque argument anticipé. Il semble que vous attendiez une chaîne d'arguments formatée de manière très spécifique plutôt que d'autoriser des valeurs définies, vous pourriez essayer :

if(args[0].Trim() == PROCESS_OPTION_ONE || args[0].Trim() == PROCESS_OPTION_TWO) 
{ 
    //Process file - Argument 2
    switch(args[1].Trim()
    {
        case PROCESS_CUSTOMER, PROCESS_ADMIN, PROCESS_MEMBER, PROCESS_GUEST, PROCESS_USER:
            // Do stuff
            break;
        default:
            // Do other stuff
            break;
    }
}

Ma méthode préférée serait quelque chose comme

foreach(string arg in args)
{
    switch(arg)
    {
        case PROCESS_CUSTOMER:
            // Set property
            break;
        ...
        default:
            // Exception?
            break;
    }
}

NOTE : args.Length == 1 est plus rapide que args.Length > 0 && args.Length < 2. C'est aussi un peu plus lisible.

1voto

John M Gant Points 6147

Vous n'avez pas besoin du else si vous êtes déjà rentré. Cela pourrait éliminer une grande partie de votre nidification. Vous pouvez également essayer d'utiliser un interrupteur au lieu d'un tas de ifs imbriqués.

1voto

Nick Points 4676

J'ai pris le code de cet article de Code Project il y a longtemps et j'en ai fait ma propre version pour les applications en ligne de commande. J'y ai apporté mes propres modifications, par exemple en faisant hériter la classe de Dictionary, etc. Mais la partie regex du code est très bonne, et rend ce genre de commutations en ligne de commande très facile.

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