如何使用不同数量的命令行参数构建对象?

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

我使用构建器模式来制作一个对象。问题是我必须从命令行获取参数。我想传递一到六个参数,并根据参数数量调用相应的方法。

例如,如果我传递 3 个参数,程序将调用前三个方法; 4 个参数的前四种方法等等;

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

有没有可能做到高效?我唯一想到的就是反思,但我不确定这是否是个好主意。

诀窍是将方法调用链分解为单独的语句,而不是尝试在一个语句中完成所有操作。将中间构建器对象保存在临时变量中,然后在最后调用 build()

ExampleClass.Builder builder = new ExampleClass.Builder();

if (args.length >= 1) { builder = builder.method1(args[0]); }
if (args.length >= 2) { builder = builder.method2(args[1]); }
if (args.length >= 3) { builder = builder.method3(args[2]); }
if (args.length >= 4) { builder = builder.method4(args[3]); }
if (args.length >= 5) { builder = builder.method5(args[4]); }
if (args.length >= 6) { builder = builder.method6(args[5]); }

ExampleClass obj = builder.build();

您有一个按照必须执行的顺序定义的方法队列。

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

您有一个由原始数组构成的参数队列。

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

鉴于方法查询总是比参数队列长,算法是

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

不一定是队列

当你 add/remove 一个方法时,你只需要关心 methods

整个(虚拟)示例:

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