Java 链接的泛化

Java generalization of chaining

我有一个 class 实现流畅的界面模式如下:

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 以下列方式使用链接。

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

....
}

我想定义一个泛型 class 而不是多个 classes A, B, C....

我该如何强制执行?

我希望如果我可以为每个方法调用定义一些常量,并在每个 classes 的构造函数中按顺序定义常量,那么我可以使用这些常量按照 class的规范。

具有与您的规则功能相匹配的功能界面 f1f2f3...:[=​​16=]

interface RuleFunction extends Function<Rules, Rules> { }

您可以编写一个 class 来应用您传递给它的任何规则组合:

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

当您构建 class 方法引用时,提供了一个方便的 shorthand 可用于引用要应用的规则:

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

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

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