Java generalization of chaining

Swagatika :

I have a class which implements fluent interface pattern as follows:

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

...
...

}

I have a few classes that use chaining in the following way.

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

....
}

I want to define a generic class instead of multiple classes A, B, C....

How can I enforce that?

I wish if I could define some constants for each method call, and define the constants in order during each classes' constructor, then I can use those constants to invoke the method as per the class's specifcation.

teppic :

With a functional interface that matches your rule functions f1, f2, f3...:

interface RuleFunction extends Function<Rules, Rules> { }

You can write a single class that will apply whatever combination of rules you pass it:

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

When you construct the class method references provide a convenient shorthand that can be used to refer to the rules to apply:

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=134471&siteId=1