불변 클래스
불변 클래스의 안정성
객체가 파괴(회수)될 순간까지 객체 내부의 값이 절대 달라지지 않음
가변 클래스에 비해 설계와 구현이 쉬우며,
오류가 덜 생김
불변 객체는
스레드 안정성(Thread-Safe)
를 보장스레드 안정성은 여러 스레드가 하나의 리소스를 동시에 사용하며 상태를 변경시키게 되면 깨지는데, 불변 객체는 애초에 상태가 변경될 일이 없어 여러 스레드에서 동시에 사용해도 문제가 없음
따라서, 불변 객체는 멀티 스레드 환경에서 안심하고 사용할 수 있음
불변 객체는
실패 원자성
을 제공상태가 변하지 않기 때문에, 일부 로직의 실패에 의해 객체가 불일치 상태에 빠질 염려가 없음
불변 클래스를 구현하는 방법
객체의 상태를 변경하는 메서드(
변경자
)를 제공하지 않아야 함하위 클래스에서 객체를 변경하는 것을 막기 위해, 확장 불가능 클래스로 선언
이를 달성하기 위한 두 가지 방법이 있음
final 클래스로 선언
private 생성자를 명시하고 정적 팩토리 메서드를 제공
모든 필드를 private으로 선언해 외부에서 이를 수정하는 것을 방지
불변과는 연관이 없으나, public으로 선언하면 외부에 노출되므로 추후 내부 표현을 바꿀 수 없음
모든 필드를 final로 선언해 생성자 호출 시점 이후의 값 변경을 막음
클래스 내부를 제외하고, 클래스 내부의 필드가 참조하는 가변 객체로의 접근을 막음
불변 클래스를 사용할 때 주의할 점
불변 클래스는 객체의 상태가 불변임을 보장해 안정성 면에서는 좋은 선택이지만,
약간의 수정이 필요한 경우에도 새 객체를 만들어야 하기 때문에
성능 문제를 일으킬 수 있음이를 예방하기 위해서는 최대한 객체를
재사용
해야 함이를 위해 정적 팩토리 메서드(Item 1)과 연관지어, 생성자를 통해 인스턴스를 획득하는 대신 정적 팩토리를 이용하고 이 메서드 내부에서
캐싱
을 이용하는 것도 좋음새 객체를 얻기 위해 여러 번의 상태 변환을 거쳐야 해서 여러 번의 중간 단계 객체가 생길 수 있는 경우에는 이들을 하나의 단계로 묶어서 처리하는 것이 좋음
불변 객체는 값이 변경되지 않기 때문에 불변 객체 간에 같은 내부 데이터를 공유해도 문제가 없음
불변 클래스는 복사 메서드를 제공할 필요가 없음
복사하는 대신 자기 자신을 이용하면 되기 때문
핵심 정리
불변 클래스는 안정성 면에서 뛰어남
불변 클래스는 성능 이슈를 야기할 수 있으나 정적 팩토리 메서드를 제공하거나 캐싱을 도입하는 등의 방법으로 일부 예방이 가능
불변으로 만드는 것이 가장 좋고, 그럴 수 없어 가변으로 만들어야 한다고 해도 최대한
변경 가능한 부분을 최소화
하는 것이 안정성 면에서 좋음합당한 이유가 없다면 필드는 private final으로 선언해 외부에서 접근 및 조작이 불가능하도록 하는 것이 좋음
Last updated