代码之家  ›  专栏  ›  技术社区  ›  Swagatika

链接的Java泛化

  •  2
  • Swagatika  · 技术社区  · 7 年前

    我有一个类,它实现了如下流畅的接口模式:

    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 回复  |  直到 7 年前
        1
  •  2
  •   teppic    7 年前

    具有与规则函数匹配的函数接口 f1 , f2 , f3 ……

    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);
    
        2
  •  0
  •   Ondřej Fischer    7 年前

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

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