Search code examples
javaarrayscommand-linebuilderbuilder-pattern

How can I build an object using a varying number of command line arguments?


I use the builder pattern to make an object. The problem is that I have to get arguments from command line. I want to pass one to six arguments and, based on the arguments amount, call the relevant methods.

For example, if I pass 3 args, the program will call first three methods; first four methods for 4 args and so on;

ExampleClass obj = new ExampleClass.Builder()
                .method1(args[0])
                .method2(args[1])
                .method3(args[2])
                .build();

Is it even possible to make it efficiently? The only thing that occurs to me is reflection, but I'm not sure if this is a good idea.


Solution

  • You have a queue of methods defined in the order in which they must be executed.

    class Builder {
        Queue<Function<String, Builder>> methods 
            = new LinkedList<>(List.of(this::method1, this::method2, this::method3));
    }
    

    You have a queue of arguments formed from a raw array.

    Queue<String> argsQueue = new LinkedList<>(Arrays.asList(args));
    

    Given that the method query is always longer than the queue of arguments, the algorithm is

    Builder builder = new ExampleClass.Builder();
    while (!argsQueue.isEmpty()) {
        builder.getMethods().poll().apply(argsQueue.poll());
    }
    ExampleClass instance = builder.build();
    

    It shouldn't necessarily be queues.

    When you add/remove a method, you would need to take care only of methods.

    The whole (dummy) example:

    class ExampleClass {
        public static void main(String[] args) {
            Queue<String> argsQueue = new LinkedList<>(Arrays.asList(args));
    
            Builder builder = new ExampleClass.Builder();
            while (!(argsQueue.isEmpty() || builder.getMethods().isEmpty())) {
                builder.getMethods().poll().apply(argsQueue.poll());
            }
            ExampleClass instance = builder.build();
        }
    
        public static class Builder {
    
            private final Queue<Function<String, Builder>> methods = new LinkedList<>(List.of(this::method1, this::method2, this::method3));
    
            public Queue<Function<String, Builder>> getMethods() {
                return methods;
            }
    
            public Builder method1(String s) {
                System.out.println("method1 " + s);
                return this;
            }
    
            public Builder method2(String s) {
                System.out.println("method2 " + s);
                return this;
            }
    
            public Builder method3(String s) {
                System.out.println("method3 " + s);
                return this;
            }
    
            public ExampleClass build() {
                System.out.println("building...");
                return new ExampleClass();
            }
        }
    }