在 Java 中重构私有实用程序方法

Refactoring a Private Utility Method in Java

我正在尝试重构 Java 中的两个私有方法,它们本质上是同一件事。我目前正在对足球决胜局做一些 JUnit 测试断言,并编写了一个实用方法,该方法流过结果并返回团队得分或失球的总进球数。它们非常相似:

    private Integer getTeamGoalsScored(final LeagueTable leagueTable, final Team team) {
        return leagueTable.getAllResults().stream()
                .filter(t -> t.getHomeTeam().equals(team))
                .map(Result::getOutcome)
                .map(Outcome::getGoalsScoredByHomeTeam).reduce(0, Integer::sum) +
                leagueTable.getAllResults().stream()
                        .filter(t -> t.getAwayTeam().equals(team))
                        .map(Result::getOutcome)
                        .map(Outcome::getGoalsScoredByAwayTeam).reduce(0, Integer::sum);
    }

    private Integer getTeamGoalsAgainst(final LeagueTable leagueTable, final Team team) {
        return leagueTable.getAllResults().stream()
                .filter(t -> t.getHomeTeam().equals(team))
                .map(Result::getOutcome)
                .map(Outcome::getGoalsScoredByAwayTeam).reduce(0, Integer::sum) +
                leagueTable.getAllResults().stream()
                        .filter(t -> t.getAwayTeam().equals(team))
                        .map(Result::getOutcome)
                        .map(Outcome::getGoalsScoredByHomeTeam).reduce(0, Integer::sum);
    }

如您所见,它们基本上是样板文件,我想知道如何将这两个合并为一个方法。我猜是 true/false、scored/against?

的布尔值

您可以提取执行过滤和映射的函数。并将它们作为参数传递给这个函数:

private Integer getSum(final LeagueTable leagueTable, 
   Function<Result, Boolean> filterFun, Function<Outcome, Integer> mapFun 
) {
        return leagueTable.getAllResults().stream()
                .filter(filterFun)
                .map(Result::getOutcome)
                .map(mapFun).reduce(0, Integer::sum);
    }

然后你可以像这样在你的代码中使用:

private Integer getTeamGoalsScored(final LeagueTable leagueTable, final Team team) {
    return getSum(leagueTable,
            t -> t.getHomeTeam().equals(team), Outcome::getGoalsScoredByHomeTeam) + 
           getSum(leagueTable,
            t -> t.getAwayTeam().equals(team), Outcome::getGoalsScoredByAwayTeam);
}

更新

正如在 ToIntFunctionPredicate 的评论中提到的那样; getSum可以这样写:

private Integer getSum(final LeagueTable leagueTable, 
   Predicate<Result> filterFun, ToIntFunction<Outcome> mapFun 
) {
        return leagueTable.getAllResults().stream()
                .filter(filterFun)
                .map(Result::getOutcome)
                .mapToInt(mapFun).sum();
    }