Java链通用化

时间:2018-11-25 02:46:10

标签: java generics fluent

我有一个实现流利的接口模式的类,如下所示:

Class Rules {

  private List<Map<String, String>> listOfMap;

public Rules getListAddresses(List<Map<String, String>> listAddresses) {
    listOfMap = new ArrayList<>(listAddresses);
    return this;
}

  public List<Map<String, String>> fOut() {
    return listOfMap;
  }

  public Rules f1() {
      listOfMap = ....;
      return this;
  }

  public Rules f2() {
      listOfMap = ....;
      return this;
  }

...
...

}

我有一些通过以下方式使用链接的类。

Class A extends Rules{

        List<Map<String, String>> listOfMap = dropActiveStatus(listOfMapInout);

        //TODO make some king of CONSTANT to function name mapping
        List<Map<String, String>> listOfMapOut = this.getListAddresses(listOfMap)
            .f1()
            .f2()
            .f3()
            .f4()
            .fOut();

....
}

Class B extends Rules{

        List<Map<String, String>> listOfMap = dropActiveStatus(listOfMapInout);

        //TODO make some king of CONSTANT to function name mapping
        List<Map<String, String>> listOfMapOut = this.getListAddresses(listOfMap)
            .f5()
            .f6()
            .fOut();

....
}

我想定义一个通用类,而不是多个类A,B,C ...

我该如何执行?

我希望如果可以为每个方法调用定义一些常量,并在每个类的构造函数中按顺序定义这些常量,那么我可以根据类的说明使用这些常量来调用该方法。

2 个答案:

答案 0 :(得分:2)

具有与您的规则功能f1f2f3 ...相匹配的功能界面:

interface RuleFunction extends Function<Rules, Rules> { }

您可以编写一个单独的类,该类将应用您通过的所有规则组合:

public class RuleApplier {
    private RuleFunction[] steps;

    public RuleApplier(RuleFunction... steps) {
        Objects.requireNonNull(steps);
        this.steps = steps;
    }

    public List<Map<String, String>> apply(List<Map<String, String>> listOfMap) {
        Rules rules = new Rules().getListAddresses(listOfMap);
        for (RuleFunction step : steps) {
            rules = step.apply(rules);
        }
        return rules.fOut();
    }
}

构造类方法时,引用提供了一个方便的速记,可用于引用要应用的规则:

List<Map<String, String>> listOfMap = dropActiveStatus(listOfMapInout);

RuleApplier applierA = new RuleApplier(Rules::f1, Rules::f2, Rules::f3, Rules::f4);
List<Map<String, String>> listOfMapOutA = applierA.apply(listOfMap);

RuleApplier applierB = new RuleApplier(Rules::f5, Rules::f6);
List<Map<String, String>> listOfMapOutB = applierB.apply(listOfMap);

答案 1 :(得分:0)

在我看来,该解决方案可以简化:

public class RuleApplier {
    private UnaryOperator<Rules> operator;

    public RuleApplier(UnaryOperator<Rules> operator) {
        Objects.requireNonNull(operator);
        this.operator = operator;
    }

    public List<Map<String, String>> apply(List<Map<String, String>> listOfMap) {
        Rules rules = new Rules().getListAddresses(listOfMap);
        return operator.apply(rules).fOut();
    }
}

然后是用法:

RuleApplier applierA = new RuleApplier(rules -> rules.f1().f2().f3().f4());
List<Map<String, String>> listOfMapOutA = applierA.apply(listOfMap);