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