如何使用不同数量的命令行参数构建对象?
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();
}
}
}
我使用构建器模式来制作一个对象。问题是我必须从命令行获取参数。我想传递一到六个参数,并根据参数数量调用相应的方法。
例如,如果我传递 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();
}
}
}