我有一堆像这样的方法:
public Result createSomething1(A a, B b, C c) {}
public Result createSomethung2(B a, C c, D d) {}
总是我需要使用流畅的api和类似的状态创建带有更新(或不是)对象的Result对象:
Result result = new Result.withA(a)
.withB(b)
.withC(c)
...withStatus("success");
我不想为每个set参数创建单独的方法。
如何编写能够从未定义数量的参数创建Result对象的泛型方法?
例如:
伪代码
Result createResult(A a, B b, C c ...) {
return with(a, b, c, ...)
}
使用
Result createSomething1(A a, B b) {
// business processing ending error
Result result = createResult(a, b);
result.withStatus("error")
return result;
}
Result createSomething2(A a, C c, M m) {
// business processing ending
Result result = createResult(c, m);
a.setFoo("foo");
result.withA(a);
return result;
}
答案 0 :(得分:1)
如果您的参数类具有相同的基本案例类: 公共类参数{ ... }
public class A extends Parameter {
...
}
public class B extends Parameter {
...
}
比你可以使用varargs
public Result with(Parameter... p) {
some code to process parameters
return result //with parameters setted
}
p - 参数数组。现在你可以打电话了
result.with(a, b, c)
或
result.with(a).with(b,c)
答案 1 :(得分:1)
在地图中存储参数会使这变得非常简单:
Map<String, Object> params;
public Result with(Object... newParams) {
for (Object param : newParams) {
params.put(param.getClass().getName(), param);
}
return this;
}
用法示例:
new Result().with(a).with(b).with(c);
或等同于:
new Result().with(a,b,c);
编辑:
如果您必须使用类字段而不是将它们存储在地图中,则可以使用反射访问它们:
public Result with(Object... newParams) {
for (Object param : newParams) {
setField(param);
}
return this;
}
public void setField(Object o) throws IllegalArgumentException, IllegalAccessException {
Field[] fields = Result.class.getFields();
for (Field field: fields) {
if (field.getType().equals(o.getClass())) {
field.set(this, o);
}
}
}
答案 2 :(得分:1)
您可能需要查看由 StringBuilder 实现的构建器设计模式。
使用一个或多个返回自身的方法ResultBuilder
创建一个with(...)
类。这样,您可以链接调用以传递所有参数。
最后,使用给定的参数创建一个方法toResult()
来创建Result对象。
看起来像这样:
public class ResultBuilder {
public ResultBuilder with(A a) {
// ...
return this;
}
public ResultBuilder with(B b) {
// ...
return this;
}
public ResultBuilder with(C c) {
// ...
return this;
}
public Result toResult() {
final Result result = new Result();
result.setA(/* ... */);
result.setB(/* ... */);
result.setC(/* ... */);
return result;
}
}
然后您可以像这样使用它:
Result result = new ResultBuilder().with(a).with(b).with(c).toResult();
答案 3 :(得分:0)
您可以使用Java 8中的Streams进行调查
这类似于Linux管道
Stream s1 = Stream.builder().add(1).add(4).add(7).build();
或类似下面的内容,将数组的每个值传递给方法
int [] myArray = {3,2,5,7,33,90};
int result = Arrays.stream(myArray).somemethod();