You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Cribbage计分应用:如何合并Java多段if语句优化代码?

问题:Android Cribbage计分应用中冗余获胜判断代码的重构优化

我正在开发一款Android平台的Cribbage计分应用,目前针对蓝队的获胜判断代码依赖大量if语句,功能正常但代码冗余。这个逻辑后续还要复用给红队和绿队。作为Java新手,我想了解合并代码、提升可读性与可维护性的最佳实践。

现有代码如下:

if(blueTeamScore >= ENDGAMESCORE) { 
    String baseVictoryText = "Blue Team has won!"; 
    TextView winningTeamTextView = (TextView) findViewById(R.id.winningTeam); 
    if(hasThreePlayer == false) { 
        winningTeamTextView.setText(baseVictoryText); 
        if (hasSkunk == true) { 
            if (redTeamScore <= 90) { 
                winningTeamTextView.setText(baseVictoryText + "\nAnd Red Team got Skunked"); 
            } 
        } 
    } 
    if(hasThreePlayer == true) { 
        winningTeamTextView.setText(baseVictoryText); 
        if (hasSkunk == true) { 
            if ((redTeamScore <= 90) && (greenTeamScore <= 90)) { 
                winningTeamTextView.setText(baseVictoryText + "\nAnd Red and Green Teams got Skunked"); 
            } 
            if ((redTeamScore <= 90) && (greenTeamScore >= 90)) { 
                winningTeamTextView.setText(baseVictoryText + "\nAnd Red Team got Skunked"); 
            } 
            if ((redTeamScore >= 90) && (greenTeamScore <= 90)) { 
                winningTeamTextView.setText(baseVictoryText + "\nAnd Green Team got Skunked"); 
            } 
        } 
    } 
}

我知道布尔变量不能用在switch语句里,想了解有没有类似的方法可以浓缩这些代码?


回答

作为Java开发者,我经常遇到这种冗余条件判断的情况,给你几个实用的重构思路,既能简化代码,又方便后续复用给红队和绿队:

1. 先封装Team类,统一管理队伍数据

首先,把每个队伍的名称、分数这些属性封装成一个Team类,这样不管是蓝队、红队还是绿队,都可以用同一个类来表示,避免单独的变量(比如blueTeamScore、redTeamScore)满天飞:

public class Team {
    private final String name;
    private final int score;

    public Team(String name, int score) {
        this.name = name;
        this.score = score;
    }

    // Getters
    public String getName() { return name; }
    public int getScore() { return score; }
}

创建队伍实例也变得更清晰:

Team blueTeam = new Team("Blue Team", blueTeamScore);
Team redTeam = new Team("Red Team", redTeamScore);
Team greenTeam = new Team("Green Team", greenTeamScore);

2. 提取通用的获胜判断方法

把重复的逻辑抽成一个独立的方法,参数传入获胜队伍、其他队伍列表、是否启用Skunk规则、目标TextView控件,这样不管哪个队伍获胜,都可以直接调用这个方法:

private void handleVictory(Team winningTeam, List<Team> otherTeams, boolean hasSkunk, TextView winningTextView) {
    // 基础获胜文本
    StringBuilder victoryText = new StringBuilder(winningTeam.getName() + " has won!");

    // 处理Skunk逻辑
    if (hasSkunk) {
        List<Team> skunkedTeams = new ArrayList<>();
        for (Team team : otherTeams) {
            if (team.getScore() <= 90) {
                skunkedTeams.add(team);
            }
        }

        // 根据被Skunk的队伍数量拼接文本
        if (!skunkedTeams.isEmpty()) {
            victoryText.append("\nAnd ");
            if (skunkedTeams.size() == 1) {
                victoryText.append(skunkedTeams.get(0).getName()).append(" got Skunked");
            } else {
                // 处理多队伍的拼接逻辑
                for (int i = 0; i < skunkedTeams.size(); i++) {
                    if (i == skunkedTeams.size() - 1) {
                        victoryText.append("and ").append(skunkedTeams.get(i).getName());
                    } else {
                        victoryText.append(skunkedTeams.get(i).getName()).append(", ");
                    }
                }
                victoryText.append(" got Skunked");
            }
        }
    }

    // 设置最终文本到TextView
    winningTextView.setText(victoryText.toString());
}

3. 简化原有的调用逻辑

现在原来的蓝队判断代码可以大幅简化,后续红队、绿队获胜的判断直接复用这个方法就行:

TextView winningTeamTextView = findViewById(R.id.winningTeam);
// 蓝队获胜判断
if (blueTeam.getScore() >= ENDGAMESCORE) {
    List<Team> otherTeams = hasThreePlayer 
        ? Arrays.asList(redTeam, greenTeam) 
        : Collections.singletonList(redTeam);
    handleVictory(blueTeam, otherTeams, hasSkunk, winningTeamTextView);
}

// 红队获胜判断(直接复用方法)
if (redTeam.getScore() >= ENDGAMESCORE) {
    List<Team> otherTeams = hasThreePlayer 
        ? Arrays.asList(blueTeam, greenTeam) 
        : Collections.singletonList(blueTeam);
    handleVictory(redTeam, otherTeams, hasSkunk, winningTeamTextView);
}

// 绿队获胜判断同理

4. 关于布尔变量的“类似switch”替代方案

你提到布尔变量不能用switch,其实我们可以用枚举类来处理多状态的情况,比纯布尔判断扩展性更好。比如把玩家数量定义成枚举:

public enum PlayerCount {
    TWO_PLAYERS, THREE_PLAYERS
}

然后在调用时用switch处理枚举:

PlayerCount playerCount = hasThreePlayer ? PlayerCount.THREE_PLAYERS : PlayerCount.TWO_PLAYERS;
List<Team> otherTeams;

switch (playerCount) {
    case TWO_PLAYERS:
        otherTeams = Collections.singletonList(redTeam);
        break;
    case THREE_PLAYERS:
        otherTeams = Arrays.asList(redTeam, greenTeam);
        break;
    // 后续加4人模式直接加枚举值即可
}

额外的小建议

  • 避免直接写魔法值(比如90),可以定义成常量:private static final int SKUNK_THRESHOLD = 90;,后续修改数值只需要改一处。
  • 尽量用if (!hasThreePlayer)代替if (hasThreePlayer == false),代码更简洁易读。
  • 如果使用AndroidX/Jetpack,建议用ViewBinding代替findViewById,避免强制类型转换的风险。

内容的提问来源于stack exchange,提问作者Jack Duane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:08:50