4

我正在处理一个基于命令行参数执行大量 if...else 分支的程序。这是在 C# 中,但我确信它适用于 Java、C++ 等。这是一般大纲:

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

所以你可以说,这有点乱。是否有一两种最适用于清理某些东西的设计模式?命令模式,也许?感谢您的建议和提示。

4

4 回答 4

4

停止嵌套。

您可以像 (+1) Joel 所说的那样进行切换,或者您可以将您的逻辑分解为清晰的方法调用。

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

然后,在您的处理方法中...

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

使您的方法尽可能简单,并将更长的、令人困惑的算法分解为不同的方法调用,这些方法调用通过它们的名称清楚地表明它们在做什么。

于 2010-02-17T16:51:30.997 回答
3

我偏爱在参数数组上使用 switch 语句,并为每个预期的参数在某种配置类中设置属性。看来你期待一个非常特别格式化的参数字符串,而不是允许设置值,你可以尝试:

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

我的首选方法是

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

注意:args.Length == 1 比 args.Length > 0 && args.Length < 2 快。它也更具可读性。

于 2010-02-17T16:38:57.857 回答
1

else如果您已经返回,则不需要。这可能会减少你的很多嵌套。您也可以尝试使用开关而不是一堆嵌套的 if。

于 2010-02-17T16:37:14.507 回答
1

很久以前,我从这篇 Code Project 文章中获取了代码,并制作了我自己的版本以用于命令行应用程序我对它做了自己的修改,比如让类继承自 Dictionary 等。但是代码的正则表达式部分非常好,并且使这些命令行开关变得容易。

于 2010-02-17T16:54:25.917 回答