本文详解如何为 Gradebook 中的 Assignment 类设计健壮、可维护的 accrueScore() mutator 方法,涵盖边界校验、极值更新、累加统计等核心逻辑,并提供完整可运行代码与关键注意事项。
本文详解如何为 gradebook 中的 assignment 类设计健壮、可维护的 `accruescore()` mutator 方法,涵盖边界校验、极值更新、累加统计等核心逻辑,并提供完整可运行代码与关键注意事项。
在面向对象编程中,mutator(修改器)方法是封装数据变更逻辑的核心机制。对于模拟课程成绩管理的 Assignment 类,accrueScore(int newScore) 不仅需安全地更新内部状态,还需严格遵循业务规则:拒绝非法分数、动态维护极值、持续累积统计量。以下是一个专业、鲁棒且符合 Java 最佳实践的实现方案。
✅ 正确实现 accrueScore()
public class Assignment {
private String name;
private int totalPoints;
private int minScore;
private int maxScore;
private int sum;
private int count;
public Assignment(String inName, int inTotalPoints) {
this.name = inName;
this.totalPoints = Math.max(0, inTotalPoints); // 防御性初始化:totalPoints ≥ 0
this.minScore = 0;
this.maxScore = 0;
this.sum = 0;
this.count = 0;
}
/**
* 将新分数加入成绩记录。仅当分数合法(0 ≤ score ≤ totalPoints)时执行更新。
* 自动维护最小分、最大分、总分和计数。
*
* @param newScore 待添加的分数
* @return 当前累计分数总数(便于链式调用或调试),若未更新则返回原 sum
*/
public int accrueScore(int newScore) {
// 规则1:范围校验 —— 分数必须在 [0, totalPoints] 闭区间内
if (newScore < 0 || newScore > totalPoints) {
return sum; // 拒绝非法输入,不改变任何状态,返回当前 sum
}
// 规则2:首次录入 —— 初始化 min/max 为当前分数
if (count == 0) {
minScore = maxScore = newScore;
} else {
// 规则3 & 4:动态更新极值(无需 else-if,因 min/max 可能同时被同一分数触发)
if (newScore > maxScore) {
maxScore = newScore;
}
if (newScore < minScore) {
minScore = newScore;
}
}
// 规则5 & 6:累加并计数
sum += newScore;
count++;
return sum;
}
// 辅助 getter(供验证与测试使用)
public int getMinScore() { return count == 0 ? 0 : minScore; }
public int getMaxScore() { return count == 0 ? 0 : maxScore; }
public double getAverage() { return count == 0 ? 0.0 : (double) sum / count; }
public int getCount() { return count; }
}? 关键设计说明
- 防御性编程:构造函数中对 inTotalPoints 做 Math.max(0, ...) 处理,避免后续范围判断失效;accrueScore() 入口即做完整边界检查( totalPoints),比原文中 0
- 首次录入的原子性:使用 count == 0 判断而非依赖初始值(如 minScore == 0),避免 totalPoints == 0 时逻辑混淆。
- 极值更新独立判断:if (newScore > maxScore) 和 if (newScore
- 返回值语义明确:返回 sum 支持链式调用(如 assignment.accrueScore(95).accrueScore(87) 不适用,但利于日志/断言),且便于单元测试验证状态一致性。
- 无副作用原则:非法输入绝不修改任何字段(包括 minScore/maxScore 的初始值),确保对象始终处于一致、可预测状态。
⚠️ 注意事项与常见陷阱
- ❌ 不要在构造函数中将 minScore/maxScore 初始化为 Integer.MAX_VALUE/Integer.MIN_VALUE:虽常见于算法题,但在此业务场景中会破坏“未录入分数时无有效极值”的语义,且易引发平均分计算错误。
- ❌ 避免在 accrueScore() 中抛出异常替代静默忽略:分数越界属于预期中的业务约束(如学生误填 150/100),应静默拒绝而非中断流程;异常适用于真正意外的故障(如 null 输入)。
- ✅ 建议补充单元测试:
@Test void testAccrueScore() { Assignment hw = new Assignment("HW1", 100); assertEquals(0, hw.getCount()); hw.accrueScore(85); assertEquals(85, hw.getMinScore()); assertEquals(85, hw.getMaxScore()); assertEquals(85, hw.getSum()); assertEquals(1, hw.getCount()); hw.accrueScore(92); assertEquals(85, hw.getMinScore()); assertEquals(92, hw.getMaxScore()); assertEquals(177, hw.getSum()); hw.accrueScore(-5); // 越界,无变化 assertEquals(2, hw.getCount()); // count 不变 }
通过以上实现,accrueScore() 不仅满足题目全部六条规则,更具备生产环境所需的健壮性、可读性与可测试性,是 Gradebook 系统中值得信赖的数据聚合入口。

















