코딩하는 털보

이펙티브 자바, 아이템 17. 변경 가능성을 최소화하라 본문

Book/이펙티브 자바

이펙티브 자바, 아이템 17. 변경 가능성을 최소화하라

이정인 2021. 9. 3. 12:44

이펙티브 자바, 아이템 17. 변경 가능성을 최소화하라

불변 객체는 단순하다. 생성된 시점의 상태를 파괴될 때까지 그대로 간직한다.
불변 클래스는 가변 클래스보다 설계하고 구현하고 사용하기 쉽고 오류가 생길 여지가 적어 안전하다.
클래스는 꼭 필요한 경우가 아니라면 불변이어야 한다. 불변으로 만들 수 없는 클래스라도 변경할 수 있는 부분을 최소화하자.

불변 클래스 만들기 규칙

  • setter를 제공하지 않는다.
    getter가 있다고 해서 무조건 setter를 만들지는 말자.
  • 클래스를 확장할 수 없게 막는다.
    가장 쉬운 방법은 final 클래스로 만들기.
    또는 모든 생성자를 private 또는 package-private으로 만들고 정적 팩토리를 제공하기.
  • 모든 필드를 final로 선언한다.
  • 모든 필드를 private으로 선언한다.
  • 자신 외에는 내부의 가변 컴포넌트에 접근할 수 없도록 한다. 방어적 복사를 사용한다.

불변 객체의 장점

  • 불변 객체는 근본적으로 thread-safe하며 따로 동기화 할 필요가 없다.
  • 불변 객체는 아무리 복사해봐야 원본과 똑같으므로 clone 메서드나 복사 생성자를 제공하지 않는게 좋다.
  • 불변 객체는 자유롭게 공유할 수 있음은 물론, 불변 객체끼리는 내부 데이터를 공유할 수 있다. (어차피 모든 필드들이 수정될 수 없으므로)
  • 객체를 만들 때 다른 불변 객체들을 구성요소로 사용하면 이점이 많다. 객체의 불변식을 유지하기 수월하다.
  • 불변 객체는 그 자체로 실패 원자성(예외가 발생한 후에도 객체가 유효한 상태를 가짐)을 제공한다. 상태가 절대 변하지 않으니 잠깐이라도 불일치 상태에 빠질 가능성이 없다.

불변 객체의 단점

  • 값이 다르면 반드시 독립된 객체로 만들어야 한다.
    • 대처 방법으로 클라이언트에서 흔히 쓰일것으로 예측되는 다단계 연산을 기본 기능으로 제공하는 것.
    • 가변 동반 클래스를 public으로 제공하기.

다른 합당한 이유가 없다면 모든 필드는 private final 이어야 한다.

생성자는 불변식 설정이 모두 완료되고 초기화가 완벽히 끝난 상태의 객체를 생성해야 한다.
확실한 이유가 없다면 생성자와 정적 팩토리 외에는 어떤 초기화 메서드도 public으로 제공해서는 안 된다.
객체를 재활용할 목적으로 상태를 다시 초기화하는 메서드도 안 된다.

Comments