Search

Item 17. 변경 가능성을 최소화하라

생성일
2023/07/27 10:36
챕터
4장 - 클래스와 인터페이스

요약

가급적 불변 객체를 많이 활용하자
불변 객체라면 생성자를 숨기고 팩터리 메서드를 제공하여 상속을 막자
불변 객체가 아니더라도 클래스 내부의 변경할 수 있는 부분을 최소로 줄이자

불변 객체

불변 클래스란 해당 인스턴스 내부 값을 수정할 수 없는 클래스를 말한다.
불변 인스턴스에 저장된 정보는 고정되어서 객체가 파괴되는 순간까지 변하지 않는다.
이런 불변 클래스는 가변 클래스보다 설계하고 구현하고 사용하기 용이하고, 오류가 생길 여지가 적고 안전하다.
불변 클래스를 만들기 위해서는 아래 5가지 규칙을 지키면 된다.
객체의 상태를 변경하는 메서드(변경자)를 제공하지 않는다.
클래스를 확장할 수 없도록 만든다.
모든 필드를 final로 선언한다.
모든 필드를 private로 선언한다.
자신 외에는 내부 가변 컴포넌트에 접근할 수 없도록 한다.
불변 객체는 단순하여 생성된 시점의 상태를 파괴될 때가지 그대로 간직하고, 모든 생성자가 클래스의 불변식을 보장한다면 프로그래머는 별다른 노력을 하지 않아도 해당 클래스는 불변으로 남는다.
불변 객체는 근본적으로 스레드 안전하여 따로 동기화할 필요가 없고, 그렇기 때문에 안심하고 공유할 수 있다.
불변 클래스는 clone 메서드나 복사 생성자를 제공하지 않는 것이 좋다.
객체를 만들 때 구성요소로 다른 불변 객체들을 사용하면, 구조가 복잡하더라도 쉽게 불변식을 유지할 수 있다.
불변 객체는 그 자체로 실패 원자성을 제공한다.
생성자는 불변식 설정이 모두 완료되어 초기화가 완벽히 끝난 상태의 객체를 생성해야 한다.
불변 객체는 값이 다르면 반드시 독립된 객체로 만들어야 한다는 단점이 있다.
이렇게 불변 객체는 장점이 많고, 특정 상황에서의 성능 저하를 제외하면 단점이 없으니 많이 사용하자.
불변으로 만들 수 없는 클래스도 변경할 수 있는 부분을 최소한으로 줄이자.

불변 객체 상속 못하게 만들기

가장 쉬운 방법은 final 클래스로 선언하는 방법이지만, 별로 유연하지 못하다.
모든 생성자를 private나 package-private로 만들고 public 정적 팩터리 메서드를 제공하여 상속을 막을 수 있다.
public이나 protected 생성자가 없어 다른 패키지에서는 해당 메서드를 확장하는게 불가능하다.
팩터리 메서드를 통해서만 생성할 수 있고, 패키지 외부에서 보기에는 사실상 final이다.