如何实现 - 创建结果的通用方法

时间:2014-08-26 11:42:41

标签: java oop generics design-patterns

我有一堆像这样的方法:

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

4 个答案:

答案 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();