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

问题描述

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

例如,如果我传递3个args,程序将调用前三个方法。前四个方法用于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();

它不一定是队列。

添加/删除方法时,只需注意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::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();
        }
    }
}