“변하지 않는 값”이 아니라, 변화가 있더라도 항상 지켜져야 하는 상태의 조건을 말합니다.
예를 들어 계좌 잔액은 입금/출금으로 계속 변하지만, 잔액은 0 미만이 되면 안 된다 같은 규칙은 항상 유지되어야 합니다.
객체지향에서 불변 조건은 품질을 좌우합니다.
불변 조건이 깨지면 그 순간부터 데이터는 “신뢰할 수 없는 상태”가 되고, 버그는 화면이 아니라 정합성(데이터 무결성) 문제로 커집니다.
“불변 조건은 객체의 신뢰도다.
한 번 깨지면, 이후 계산은 전부 의심해야 한다.”
👍 GOOD (불변 조건이 살아있는 코드)
- 객체가 생성될 때부터 유효한 상태만 허용
- 상태 변경은 메서드를 통해서만 가능(검증 포함)
- 불변 조건이 코드로 강제되어 “깨질 수가 없음”
- 호출자는 객체를 믿고 로직을 단순하게 작성 가능
👎 BAD (불변 조건이 깨지기 쉬운 코드)
- setter로 아무나 상태 변경 가능
- 검증이 서비스/컨트롤러 등 외부로 흩어짐
- “나중에 검증” → 이미 DB에 잘못된 값이 들어감
- 결국 코드 곳곳에 if로 방어 로직이 늘어남
// 예시: 잔액(balance)은 어떤 상황에서도 0 미만이 될 수 없다 (불변 조건)
class Account {
private int balance;
public Account(int initial) {
if (initial < 0) throw new IllegalArgumentException("balance must be >= 0");
this.balance = initial;
}
public void deposit(int amount) {
if (amount <= 0) throw new IllegalArgumentException("amount must be > 0");
this.balance += amount;
}
public void withdraw(int amount) {
if (amount <= 0) throw new IllegalArgumentException("amount must be > 0");
if (this.balance < amount) throw new IllegalStateException("insufficient balance");
this.balance -= amount;
}
public int balance() {
return balance;
}
}
// 핵심: "balance >= 0" 규칙이 객체 밖으로 새지 않게 만든다.
💡 TIP / 참고사항
불변 조건을 지키는 가장 강력한 방법은 “상태 변경 경로를 줄이는 것”입니다.
즉, 필드 직접 수정 금지 + 의미 있는 메서드로만 변경 + 생성 시점부터 유효한 값만 허용이 3종 세트입니다.
✅ 핵심 요약
- ✔️ 불변 조건은 객체/시스템이 언제나 만족해야 하는 규칙이다.
- ✔️ 불변 조건이 깨지면 데이터 신뢰가 무너지고, 정합성/보안/금전 사고로 이어질 수 있다.
- ✔️ 가장 좋은 방법은 객체 내부 메서드로만 상태를 변경하게 해서 규칙을 강제하는 것이다.