Clamp once in the setter; delegate from everywhere else.
Bounded state with relative updates (damage, heal) cleanly delegates back to the clamping setter.
When a field has bounds and multiple methods update it relatively, the cleanest design has one setter that handles clamping and other mutators that delegate to it. This keeps the clamping logic in one place.
On the AP exam, this pattern appears in any health/score/balance class where the field is bounded.
All mutators call setHealth.
Single source of truth for the bound.
Player class
public class Player {
private int health;
private static final int MIN = 0, MAX = 100;
public Player() { health = MAX; }
public void setHealth(int newHealth) {
if (newHealth < MIN) newHealth = MIN;
if (newHealth > MAX) newHealth = MAX;
this.health = newHealth;
}
public void takeDamage(int amount) {
setHealth(health - amount);
}
public void heal(int amount) {
setHealth(health + amount);
}
public int getHealth() { return health; }
public boolean isAlive() { return health > 0; }
}
Why this is cleaner than direct manipulation
Without delegation, takeDamage and heal would each need to check bounds — three places to maintain. Delegation puts the logic in one method.
Delegation vocabulary.
Used in clean class design.
- Delegation — one method calling another to share logic.
- Single source of truth — one location where rules live.
- Helper method — method called by others to do shared work.
- Relative update — change based on current value.
- Absolute setter — sets to a specific value with clamping.
How delegation is tested.
DRY structure and correct clamping.
- setHealth handles clamping once. Don't repeat in damage/heal.
- Delegate by computing new value.
setHealth(health - amount). - Both bounds checked. Min and max.
- isAlive uses health. Don't track separately.
Trace a Player through combat.
Each call delegates to setHealth.
- p.takeDamage(30) → setHealth(70) → health=70.
- p.takeDamage(150) → setHealth(-80) → clamped to 0; isAlive()=false.
- p.heal(50) → setHealth(50) → health=50.
- p.heal(100) → setHealth(150) → clamped to 100.
Delegation pitfalls.
Duplication breaks DRY.
- Repeating clamp in damage/heal. Inconsistencies creep in.
- Direct field assignment. Skips clamping.
- Missing one bound. Negative or above-max health slips through.
- Calling damage internally without delegating. Reintroduces duplication.
Delegation pattern.
One setter; many callers.
Clamp + Delegate Reference
AP Quick Reference| Role | Method | Calls |
|---|---|---|
| Absolute setter | setHealth(value) | Clamps, assigns. |
| Damage | takeDamage(amount) | setHealth(health - amount) |
| Heal | heal(amount) | setHealth(health + amount) |
| Query | isAlive | health > 0 |
How to master delegation.
One clamp; everything delegates to it.
- MCQ Practice — verify the setter handles both bounds; other mutators call it.
- Java Lab — build Player; test damage/heal that under- and over-flow.
- FRQ Practice — write the clamping setter first; delegate everything else.
Practice — attempt these now.
AP-style assessments aligned to this lesson. Time them.
AP CSA Unit 13 Topic 08 Clamped State with Helper Delegation FRQ Practice
AP-style topic practice assessment