Java 具有两个输出的重构方法

Java 具有两个输出的重构方法,java,groovy,functional-programming,refactoring,Java,Groovy,Functional Programming,Refactoring,背景 我在负责重构的代码中遇到了许多方法,它们遵循以下一般模式: 接受复合输入 根据某些标准查找组合的子级 从复合中删除子项,但要跟踪它们 返回更新的组合并将删除的子项附加到输出参数集合 在代码中,它如下所示: public Composite trim(Composite composite, List<Child> removed){ for (Child child : composite.getChildren()){ if (criterion(child)

背景

我在负责重构的代码中遇到了许多方法,它们遵循以下一般模式:

  • 接受复合输入
  • 根据某些标准查找组合的子级
  • 从复合中删除子项,但要跟踪它们
  • 返回更新的组合并将删除的子项附加到输出参数集合
  • 在代码中,它如下所示:

    public Composite trim(Composite composite, List<Child> removed){
    
      for (Child child : composite.getChildren()){
    
        if (criterion(child)){
          composite.remove(child);
          removed.add(child);
        }
      }
    }
    
    def trim(Composite composite, Closure removeCriterion) {
        List<Child> removedChildren = composite.children.findAll(removeCriterion)
        List<Child> remainingChildren = composite.children - removedChildren
        Composite filteredComposite = new Composite(children: remainingChildren)
        [filteredComposite, removedChildren]
    }
    
    公共复合修剪(复合复合,列表已删除){
    for(子项:composite.getChildren()){
    if(标准(儿童)){
    复合。移除(儿童);
    删除。添加(子项);
    }
    }
    }
    
    这里有很多代码的味道,但我想解决的是如何将其重构为不可变的代码,从而不写入输出参数

    可能,但不是那么优雅的解决方案

    public Map<String, Object> trim(Composite composite){
    
      final List<Child> removableChildren = filter(composite);
      final Composite trimmed = copyCompositeWithoutChildren(composite, removableChildren);
    
      return wrapInMap(removableChildren, trimmed);
    }
    
    公共地图修剪(复合){
    最终列表removableChildren=过滤器(复合);
    最终复合修剪=copyCompositeWithoutChildren(复合,removableChildren);
    返回wrapInMap(removableChildren,修剪);
    }
    
    问题

    public Map<String, Object> trim(Composite composite){
    
      final List<Child> removableChildren = filter(composite);
      final Composite trimmed = copyCompositeWithoutChildren(composite, removableChildren);
    
      return wrapInMap(removableChildren, trimmed);
    }
    
    有没有更简洁的方法来实现这一点,例如,使用函数式编程方法(如groovy或Java8中的collect或splice)在JavaPre-8中提供更好(尽管更详细)的方法?如能提供任何一种语言的示例,将不胜感激

    编辑:

    第二种可能的解决方案

    public Map<String, Object> trim(Composite composite){
    
      final List<Child> removableChildren = filter(composite);
      final Composite trimmed = copyCompositeWithoutChildren(composite, removableChildren);
    
      return wrapInMap(removableChildren, trimmed);
    }
    
    灵感来源:使用策略模式

    public interface FilterStrategy {
      List<Child> filter(List<Child> children);
    }
    
    public interface RemovalResponseStrategy {
      void respond(List<Child> removedChildren);
    }
    
    public class CompositeTrimmer {
    
      private final FilterStrategy filterStrategy;
      private final RemovalResponseStrategy removalResponseStrategy;
    
      public Composite trim(final Composite composite){
    
        final List<Child> removableChildren = 
          filterStrategy.filter(composite.getChildren());
    
        final Composite trimmed = 
          copyCompositeWithoutChildren(composite, removableChildren);
    
        removalResponseStrategy.respond(removableChildren);  
    
        return trimmed;
      }
    }
    
    公共接口过滤器策略{
    列表过滤器(列出子项);
    }
    公共接口移除ResponseStregy{
    无效响应(列出移除的子项);
    }
    公共类复合器{
    私人最终筛选策略筛选策略;
    私人最终拆迁责任范围拆迁责任范围;
    公共复合材料饰件(最终复合材料){
    最终列表removableChildren=
    filterStrategy.filter(composite.getChildren());
    最终复合修剪=
    copyCompositeWithoutChildren(复合、可移除的子对象);
    RemovalResponseStregy.Response(removableChildren);
    返回修剪;
    }
    }
    
    你没有说你有什么样的自由来改变
    复合类,或者哪些方法是
    已经有了。所以我只是编了些东西。它可能会重新安装到您现有的位置
    很容易

    更具groovy风格的解决方案如下:

    public Composite trim(Composite composite, List<Child> removed){
    
      for (Child child : composite.getChildren()){
    
        if (criterion(child)){
          composite.remove(child);
          removed.add(child);
        }
      }
    }
    
    def trim(Composite composite, Closure removeCriterion) {
        List<Child> removedChildren = composite.children.findAll(removeCriterion)
        List<Child> remainingChildren = composite.children - removedChildren
        Composite filteredComposite = new Composite(children: remainingChildren)
        [filteredComposite, removedChildren]
    }
    

    非常感谢。关于改变复合类和注入行为的观点改变了我对这个问题的看法。我将根据这一反思编写另一个解决方案。