본문 바로가기
Web/OOP

[OOP] 불변 객체와 메서드명 관례 - withXxx()

by 클레어몬트 2024. 8. 20.

불변 객체(Immutable Object)는 한 번 생성되면 그 상태를 변경할 수 없는 객체를 의미한다

주요 특징

  1. 상태 불변성: 객체가 생성된 이후에는 객체의 상태(필드 값)를 변경할 수 없다. 모든 필드는 초기화된 후에 변하지 않으며, 수정이 불가능하다.
  2. 단순성: 불변 객체는 상태 관리가 단순하다. 상태가 변하지 않으므로, 복잡한 상태 변경 로직을 고려할 필요가 없다.

불변 객체의 예

  • Java의 String 클래스: String 객체는 불변 객체의 대표적인 예이다. String 객체가 생성된 후에는 해당 문자열의 내용을 변경할 수 없다. 문자열을 조작하는 메서드(예: concat, replace)는 항상 새로운 String 객체를 반환하며, 기존 객체는 변하지 않는다.
  • 래퍼 클래스 (Integer, Double, Boolean 등): 기본형 타입을 객체로 감싸는 래퍼 클래스도 불변 객체이다. 예를 들어, Integer 객체는 생성된 이후에 그 값을 변경할 수 없다.

불변 객체를 만드는 방법

  1. 모든 필드를 final로 선언: 필드를 final로 선언하면, 객체가 생성될 때 필드가 반드시 초기화되고, 이후에는 값을 변경할 수 없다.
  2. 필드를 private으로 선언: 외부에서 직접 필드에 접근하여 변경할 수 없도록 필드를 private으로 선언한다.
  3. Setter 메서드 제공 금지: 필드 값을 변경할 수 있는 Setter 메서드를 제공하면 안 된다.
  4. 생성자에서 모든 필드 초기화: 모든 필드를 한 번만 초기화하도록 생성자에서 값을 설정한다.
  5. 가변 객체를 필드로 사용하지 않기: 불변 객체 내에서 가변 객체(예: List, Map, Date)를 필드로 사용해야 한다면, 이 필드를 변경할 수 없도록 조치해야 한다. 예를 들어, 가변 객체의 복사본을 생성해 필드로 저장하거나, 가변 객체의 불변 버전을 사용하는 방식으로 처리할 수 있다.

불변 객체의 활용

  1. 캐시: 캐시 일관성을 유지하는 데 도움을 주며, 캐시에서의 히트율을 높일 수 있다. 또한, 불변 객체는 동일한 상태를 가지는 객체를 여러 번 생성하지 않고, 캐시된 객체를 재사용할 수 있어 메모리 효율성도 높다.
  2. 멀티스레드: 불변 객체는 여러 스레드가 동시에 접근하더라도 상태가 변경되지 않기 때문에, 추가적인 동기화 없이도 스레드로부터 안전하다.
  3. 엔티티의 값 타입: 값 타입이란, 객체의 동일성을 참조하는 것이 아니라 그 내용 자체가 동일한지를 확인하는 타입을 의미한다. 불변 객체는 상태가 변경되지 않으므로, 동일한 값에 대해 동일한 결과를 보장할 수 있다. 예를 들어, 두 개의 불변 객체가 같은 값을 가지면, 이 둘은 동일한 것으로 간주될 수 있다. 이로 인해, 불변 객체는 값 타입으로 사용할 때 객체의 상태 변화로 인한 예기치 않은 동작을 방지할 수 있으며, 코드의 예측 가능성을 높인다.

 

※ 불변 객체에서 값을 변경하는 경우 withYear()처럼 "with"로 시작하는 경우가 많다.
예를 들어 "coffee with sugar"라고 하면, 커피에 설탕이 추가되어 원래의 상태를 변경하여 새로운 변형을 만든다는 것을 의미한다.
이 개념을 프로그래밍에 적용하면, 불변 객체의 메서드가 "with"로 이름 지어진 경우, 그 메서드가 지정된 수정사항을 포함하는 객체의 새 인스턴스를 반환한다는 사실을 뜻한다.
정리하면 "with"은 관례처럼 사용되는데, 원본 객체의 상태가 그대로 유지됨을 강조하면서 변경사항을 새 복사본에 포함하는 과정을 간결하게 표현한다.

 

 

 

 

 

 

 

참고 및 출처: 김영한의 실전 자바 - 중급 1편

https://www.inflearn.com/course/%EA%B9%80%EC%98%81%ED%95%9C%EC%9D%98-%EC%8B%A4%EC%A0%84-%EC%9E%90%EB%B0%94-%EC%A4%91%EA%B8%89-1