4

I have a question regarding structuring of code.

I have let us say three types of packages A,B and C.

Now, classes in package A contains classes which contain the main() function. These classes need some command line arguments to run.

In package B, there are classes which contains some public variables, which need to be configured, at different times. For example before calling function A, the variable should be set or reset, the output differs according to this variable.

In package C, uses the classes in package B to perform some tasks. They do configure their variables as said before. Not only when the object is created, but also at intermediate stage.

Package A also has classes which in turn use classes from package B and package C. In order to configure the variables in classes of B and C, class in package A containing the main() function, reads command line arguments and passes the correct values to respective class.

Now, given this scenario, I want to use Apache Commons CLI parser.

I am unable to understand how exactly I should write my code to be structured in an elegant way. What is a good design practice for such scenario.

Initially I wrote a class without Apache to parse the command line arguments.

Since I want a suggestion on design issue, I will give an excerpt of code rather than complete code.

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.");
    }
     }
}

Points to note -

  • I already have 50+ command line options and they are all in one place.
  • Every class uses only a group of command line options.

I tried to write an interface, somehow but I am unsuccessful. I am not sure if this is a good way to do it or not. I need some design guidelines.

Here is the code which I wrote -

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

I think the problems in such writing of code are -

  • There are different types of arguments like int, double, string, boolean. How to handle them all.
  • getClassOption() and setClassOption() both contain the arguments "A", "B" for example. This code is prone to errors made while writing code, which I would like to eliminate.
  • I think the code is getting repetitive here, which could be encapsulated somehow in another class.
  • Not all the arguments are required, but can be ignored.

Thank You !

1
  • 1
    Please post your interface attempt, your code as presented has not obvious problems. You might consider using Commons CLI. Commented Dec 13, 2013 at 16:45

2 Answers 2

5

I would recommend to you JCommander.

I think it's a really good Argument Parser for Java.

You define all the Argument stuff within annotations and just call JCommander to parse it. On top of that it also (based on your annotations) can print out the corresponding help page. You don't have to take care about anything.

I believe you will love it! :)

Take a look at it: http://jcommander.org/ There are a lot of examples and such!

Good Luck! :)

Sign up to request clarification or add additional context in comments.

Comments

2

simple example for command line argument

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 Comment

This code literally does nothing. Equivalent code would be: ` public static void main(String args[]) { for (String arg:args) System.out.println(arg); } which also doesn't answer original question in any shape or form.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.