Java中解析命令行参数的代码结构

4

关于代码结构的问题,我有一个疑问。

假设我有三种类型的包A、B和C。

现在,包A中的类包含包含main()函数的类。这些类需要一些命令行参数才能运行。

在包B中,有一些包含一些公共变量的类,这些变量需要在不同的时间进行配置。例如,在调用函数A之前,应该设置或重置变量,输出根据此变量而异。

在包C中,使用包B中的类执行一些任务。它们确实像上面说的那样配置它们的变量。不仅在对象创建时,而且在中间阶段也是如此。

包A还有一些类,这些类又使用来自包B和包C的类。为了配置B和C类中的变量,包含main()函数的A类读取命令行参数,并将正确的值传递给相应的类。

现在,考虑到这种情况,我想使用Apache Commons CLI解析器。

我无法理解我应该如何编写我的代码以使其结构优雅。对于这种情况,有哪些好的设计实践呢?

最初,我编写了一个没有使用Apache的类来解析命令行参数。

由于我想要一个关于设计问题的建议,所以我将给出代码摘录而不是完整代码。

public class ProcessArgs 
{
     private String optionA= "default";
     private String optionB= "default";
     private String optionC= "default";

     public void printHelp ()
     {
         System.out.println ("FLAG : DESCRIPTION : DEFAULT VALUE");
         System.out.println ("-A <Option A> : Enable Option A : " + optionA);
         System.out.println ("-B <Option B> : Enable Option B : " + optionB);
         System.out.println ("-C <Option C> : Enable Option C : " + optionC); 
     }

     public void printConfig()
     {
         System.out.println ("Option A " + optionA);
         System.out.println ("Option B " + optionB);
         System.out.println ("Option C " + optionC);
     }

     public void parseArgs (String[] args)
     {
        for (int i=0;i<args.length;i++)
        {
        if (args[i].equalsIgnoreCase ("-A"))
           optionA = args[++i];
        else if (args[i].equalsIgnoreCase ("-B"))
           optionB = args[++i];
        else if (args[i].equalsIgnoreCase ("-C"))
           optionC = args[++i];
        else
           throw new RuntimeException ("Wrong Argument : " + args[i] + " :: -h for Help.");
    }
     }
}

需要注意的点 -

  • 我已经有50多个命令行选项,并且它们都在一个地方。
  • 每个类只使用一组命令行选项。

我曾经试着写一个接口,但是不成功。我不确定这是否是一个好的方法。我需要一些设计指南。

这是我写的代码 -

public interface ClassOptions 
{
    Options getClassOptions();
    void setClassOptions(Options options);
}

public class Aclass implements ClassOptions
{
    private String optionA="defaultA";
    private String optionB="defaultB";

    public Options getClassOptions()
    {
        Options options = new Options();    

        options.addOption("A", true, "Enable Option A");
        options.addOption("B", true, "Enable Option B");        

        return options;
    }

    public void setClassOptions(Options options, String args[])
    {
        CommandLineParser parser = new BasicParser();
        CommandLine cmd=null;
        try 
        {
            cmd = parser.parse( options, args);
        } catch (ParseException e) 
        {
            // TODO Auto-generated catch block
            // e.printStackTrace();
            System.out.println("ignored option");
        }

        if(cmd.hasOption("A"))
            optionA = "enabled";

        if(cmd.hasOption("B"))
            optionB = "enabled";    
    }
}

我认为编写代码中存在以下问题:
  • 有不同类型的参数,如int、double、string、boolean。如何处理它们。
  • getClassOption()和setClassOption()都包含"A"、"B"等参数。这段代码容易出现错误,我想消除这种情况。
  • 我认为这里的代码有些重复了,可以通过某种方式封装到另一个类中。
  • 并非所有参数都是必需的,但可以被忽略。
谢谢!

1
请发布您的接口尝试,您呈现的代码没有明显的问题。您可以考虑使用Commons CLI - Elliott Frisch
2个回答

5
我建议您使用JCommander。我认为它是Java的一个非常好的参数解析器。您可以在注释中定义所有参数内容,然后只需调用JCommander进行解析。此外,它还可以(基于您的注释)打印相应的帮助页面,您无需担心任何事情。我相信您会喜欢它!:)请看这里:http://jcommander.org/有很多示例等待您去发现!祝您好运!:)

2

命令行参数的简单示例

class CMDLineArgument
{
    public static void main(String args[])
    {
    int length=args.length();
    String array[]=new String[length];
    for(int i=0;i<length;i++)
    {
        array[i]=args[i];
    }
    for(int i=0;i<length;i++)
    {
        System.out.println(array[i]);
    }

1
这段代码实际上什么也不做。等价的代码是:public static void main(String args[]) { for (String arg:args) System.out.println(arg); }它也无法以任何形式回答原始问题。 - lazanet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接