构建动态足球联赛表格生成器。足球排行榜。每个团队进行多次比赛,每场比赛的结果将构成表格。
有人建议避免使用if-else语句吗?
matches.stream().forEach(match -> {
// Find the record of home team and away team in the league table
homeTeamRecord = tableEntries.stream().filter(t -> t.getTeamName().equals(match.getHomeTeam())).findFirst().get();
awayTeamRecord = tableEntries.stream().filter(t -> t.getTeamName().equals(match.getAwayTeam())).findFirst().get();
/*If home team score > away team score, then
* home team + 3 points
* home team's wins + 1
* away team's lost + 1
*/
if (match.getHomeScore() > match.getAwayScore()) {
homeTeamRecord.setPoints(homeTeamRecord.getPoints() + 3);
homeTeamRecord.setWon(homeTeamRecord.getWon() + 1);
awayTeamRecord.setLost(awayTeamRecord.getLost() + 1);
/*If home team score < away team score, then
* away team + 3 points
* away team's wins + 1
* home team's lost + 1
*/
} else if (match.getHomeScore() < match.getAwayScore()) {
awayTeamRecord.setPoints(awayTeamRecord.getPoints() + 3);
awayTeamRecord.setWon(awayTeamRecord.getWon() + 1);
homeTeamRecord.setLost(homeTeamRecord.getLost() + 1);
/*If home team score equals to away team score, then
* home team + 1 point
* away team + 1 point
* home team's draws + 1
* away team's draws + 1
*/
} else if (match.getHomeScore() == match.getAwayScore()) {
homeTeamRecord.setPoints(homeTeamRecord.getPoints() + 1);
awayTeamRecord.setPoints(awayTeamRecord.getPoints() + 1);
homeTeamRecord.setDrawn(homeTeamRecord.getDrawn() + 1);
awayTeamRecord.setDrawn(awayTeamRecord.getDrawn() + 1);
}
// Calculate 'played', 'goals for', 'goals against', 'goal difference' of home team and away team according to their latest match result
homeTeamRecord.setPlayed(homeTeamRecord.getPlayed() + 1);
awayTeamRecord.setPlayed(awayTeamRecord.getPlayed() + 1);
homeTeamRecord.setGoalsFor(homeTeamRecord.getGoalsFor() + match.getHomeScore());
awayTeamRecord.setGoalsFor(awayTeamRecord.getGoalsFor() + match.getAwayScore());
homeTeamRecord.setGoalsAgainst(homeTeamRecord.getGoalsAgainst() + match.getAwayScore());
awayTeamRecord.setGoalsAgainst(awayTeamRecord.getGoalsAgainst() + match.getHomeScore());
homeTeamRecord.setGoalDifference(homeTeamRecord.getGoalDifference() + match.getHomeScore() - match.getAwayScore());
awayTeamRecord.setGoalDifference(awayTeamRecord.getGoalDifference() + match.getAwayScore() - match.getHomeScore());
// Update the league table with the latest team record
tableEntries.set(tableEntries.indexOf(homeTeamRecord), homeTeamRecord);
tableEntries.set(tableEntries.indexOf(awayTeamRecord), awayTeamRecord);
});
答案 0 :(得分:1)
长话短说:保留您的条件陈述。
我们通常建议您将它们重构为子类,因为它们代表不同的抽象,但是您不应该使用这种子类。
作为子类的替代方法,在Map<Predicate<Match, BiConsumer<Team,Team>>
中定义它们不一定是最好的方法。
这里有3种情况需要检查:
要确定实际案例,您需要比较两个团队的计算结果。
条件语句似乎是执行任务的正确方法。
假设您引入了一种抽象方法,以使用ResultRule
方法摆脱诸如boolean applyRule(Match match, Team homeTeamRecord, Team awayTeamRecord)
接口之类的链式条件语句,并将每种情况的逻辑作为ResultRule
的3个子类进行移动。
例如HomeWinRule
看起来像:
public HomeWinRule implements ResultRule{
public boolean applyRule(Match match, Team homeTeamRecord, Team awayTeamRecord){
if (match.getHomeScore() > match.getAwayScore()) {
homeTeamRecord.setPoints(homeTeamRecord.getPoints() + 3);
homeTeamRecord.setWon(homeTeamRecord.getWon() + 1);
awayTeamRecord.setLost(awayTeamRecord.getLost() + 1);
return true;
}
return false;
}
好吗?
引入此类和这些子类并不会带来太大的价值,因为功能上的情况是有限的:胜利/失败/平等。您可能不会添加或删除新案例,案例内部的逻辑非常简单。此外,条件语句不会消失,而是会进入子类,您会注意到,因为这里您不依赖多态,而是依赖一系列规则检查/应用。
当可以经常添加/删除/修改规则时,这种模式很有意义,因此您想将其隔离。
答案 1 :(得分:1)
我同意davidxxx的观点,在这种特殊情况下,if
语句比其他任何方法都更好。但是,如果您确实必须执行此操作,或者希望通过练习了解如何执行此操作,则可以尝试以下操作:
int d = Integer.signum(match.getHomeScore() - match.getAwayScore());
如果主队获胜,这将产生1
,如果是平局则为0,如果客队取得胜利则为-1
。 (不管实际分数有多大。)
然后考虑一下:
int[] pointTable = { 0, 1, 3 };
int points = pointTable[d + 1];
这将产生0
,1
或3
,具体取决于是否有客胜,平局或主场胜利。
(甚至可能有一些从points
来计算d
的方法,它只涉及数学函数而不涉及表查找,但我怀疑通过查看它会更容易理解。) / p>
因此,一旦有了d
和points
,您要做的就是从问题中显示的每个字段中分别加上或减去d
和points
。无需if
条语句。
这个想法的实际实现留给读者练习。
(我们在这里为您提供帮助,我们不是在这里为您做功课。)
(另外:“程序代码”一词中的“代码”一词是 不可计数 。没有“代码”之类的东西。)