상세 컨텐츠

본문 제목

클래스 불변식(Class Invariant)

개발자를위한다양한이야기

by codeon 2024. 12. 31. 15:37

본문

반응형

클래스 불변식(Class Invariant)은 객체의 상태가 항상 만족해야 하는 조건 또는 규칙을 의미합니다. 즉, 객체가 생성된 이후부터 소멸될 때까지 특정 속성이나 관계가 항상 참(true)이어야 한다는 것입니다. 이러한 불변식은 객체의 일관성과 안정성을 보장하는 데 중요한 역할을 합니다.

 

클래스 불변식(Class Invariant)
클래스 불변식(Class Invariant)

 

불변식의 의미:

어떤 클래스가 있을 때, 그 클래스의 객체는 특정 조건을 만족해야 정상적인 상태로 간주될 수 있습니다. 이러한 조건을 불변식이라고 합니다. 예를 들어, Person 클래스가 있고, 나이를 나타내는 age 속성이 있다면, age는 0보다 크거나 같아야 한다는 것이 불변식이 될 수 있습니다. 만약 age가 음수 값을 가지게 된다면, 이는 객체의 상태가 비정상적인 것이므로 불변식이 깨진 것입니다.

불변식의 중요성:

  • 객체의 일관성 유지: 불변식은 객체의 상태가 예측 가능하고 일관성을 유지하도록 합니다. 이를 통해 객체를 사용하는 코드의 오류를 줄일 수 있습니다.
  • 프로그램의 안정성 향상: 불변식이 지켜지지 않으면 객체의 상태가 예기치 않게 변경될 수 있으며, 이는 프로그램의 오류나 예외를 발생시킬 수 있습니다. 불변식을 통해 이러한 문제를 예방할 수 있습니다.
  • 코드의 가독성 및 유지보수성 향상: 불변식을 명확하게 정의하면 코드의 의도를 명확하게 전달할 수 있으며, 코드의 유지보수성을 향상시킬 수 있습니다.
  • 동시성 프로그래밍의 안전성 확보: 불변 객체(Immutable Object)는 불변식을 이용하여 스레드 안전성을 확보합니다. 객체의 상태가 변하지 않으므로 여러 스레드가 동시에 접근해도 데이터의 불일치 문제가 발생하지 않습니다.

불변식의 예시:

  • 은행 계좌 (BankAccount):
    • 잔액(balance)은 0보다 크거나 같아야 합니다.
    • 계좌 번호는 고유해야 합니다.
  • 사각형 (Rectangle):
    • 너비(width)와 높이(height)는 0보다 커야 합니다.
  • 날짜 (Date):
    • 월(month)은 1부터 12 사이의 값이어야 합니다.
    • 일(day)은 해당 월의 유효한 날짜 범위 내에 있어야 합니다.

불변식을 유지하는 방법:

  • 생성자에서 검사: 객체를 생성할 때 생성자에서 입력 값을 검사하여 불변식을 위반하는 값이 들어오지 않도록 합니다.
  • Setter 메서드에서 검사: 객체의 속성을 변경하는 Setter 메서드에서 입력 값을 검사하여 불변식을 위반하는 값이 설정되지 않도록 합니다.
  • 불변 객체 사용: 객체의 상태를 변경하지 못하도록 설계하여 불변식을 강제합니다. (예: String, Integer 등)
  • Assertion 사용: 개발 단계에서 Assertion을 사용하여 불변식이 지켜지는지 확인할 수 있습니다.

Java에서의 불변식 구현 예시:

public class BankAccount {
    private final String accountNumber;
    private int balance;

    public BankAccount(String accountNumber, int initialBalance) {
        if (initialBalance < 0) {
            throw new IllegalArgumentException("Initial balance cannot be negative.");
        }
        this.accountNumber = accountNumber;
        this.balance = initialBalance;
    }

    public void deposit(int amount) {
        if (amount <= 0) {
            throw new IllegalArgumentException("Deposit amount must be positive.");
        }
        this.balance += amount;
    }

    public void withdraw(int amount) {
        if (amount <= 0) {
            throw new IllegalArgumentException("Withdrawal amount must be positive.");
        }
        if (amount > this.balance) {
            throw new IllegalArgumentException("Insufficient balance.");
        }
        this.balance -= amount;
    }

    // accountNumber는 final이므로 Setter가 없음 (불변)
    public String getAccountNumber() {
        return accountNumber;
    }

    public int getBalance() {
        return balance;
    }
}

 

반응형

관련글 더보기