Pergunta

Estou lidando com um programa que faz muitas ramificações if...else com base em argumentos de linha de comando.Isso está em C#, mas tenho certeza de que é aplicável a Java, C++ etc.Aqui está o esboço geral:

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
                        )
                    {

Então, como você pode ver, é uma bagunça.Existe um ou dois padrões de design que seriam mais aplicáveis ​​para limpar algumas coisas?Padrão de comando, talvez?Obrigado pelos conselhos e dicas.

Foi útil?

Solução

Tenho preferência por usar instruções switch na matriz de argumentos e definir propriedades em algum tipo de classe de configuração para cada argumento antecipado.Parece que você está esperando uma string de argumento formatada de maneira muito específica, em vez de permitir valores definidos. Você pode tentar:

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;
    }
}

Meu método preferido seria algo como

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

OBSERVAÇÃO:args.Length == 1 é mais rápido que args.Length > 0 && args.Length < 2.Também é um pouco mais legível.

Outras dicas

Pare de aninhar.

Você pode mudar como (+1) Joel disse, ou pode simplesmente dividir sua lógica em chamadas de método claras.

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;
}

então, em seus métodos de processo...

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

Mantenha seus métodos o mais simples possível e divida algoritmos mais longos e confusos em chamadas de métodos distintos que, por meio de seus nomes, fornecem uma indicação clara do que estão fazendo.

Você não precisa do else se você já retornou.Isso pode eliminar muito do seu aninhamento.Você também pode tentar usar um switch em vez de vários ifs aninhados.

eu peguei o código deste artigo do Code Project há muito tempo e fiz minha própria versão para usar em aplicativos de linha de comando.Eu fiz minhas próprias modificações, como fazer a classe herdar do Dicionário, etc.Mas a parte regex do código é muito boa e torna esse tipo de troca de linha de comando muito fácil.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top