변경 불가능 클래스는 그 객체를 수정할 수 없는 클래스다. 변경 불가능 클래스는 변경 가능 클래스보다 설계하기 쉽고, 구현하기 쉬우며, 사용하기도 쉽다. 오류 가능성도 적고, 더 안전하다

규칙1. 객체 상태를 변경하는 메서드를 제공하지 않는다(setter)

규칙2. 계승할 수 없도록 한다.  

그러면 잘못 작성되거나 악의적인 하위 클래스가 객체 상태가 변경된 것처럼 동작해서 변경 불가능성을 깨뜨리는 일을 막을 수 있다. 클래스에 final을 붙히면 된다.

규칙3. 모든 필드를 final로 선언한다.

그러면 시스템이 강제하는 형태대로 프로그래머의 의도가 분명하게 전달된다. 동기화없이 쓰레드에도 안전하다.

규칙4. 모든 필드를 private로 선언한다.

그러면 클라이언트가 참조하는 변경 가능 객체를 직접 수정하는 일을 막을 수 있다. 

규칙5. 변경 가능 컴포넌트에 대한 독점적 접근권을 보장한다.

클래스에 포함된 변경 가능 객체에 대한 참조를 클라이언트는 획득할 수 없어야 한다. 클라이언트가 제공하는 객체로 초기화해서도 안되고, 접근자 또한 그런 필드를 반환해서는 안된다. 따라서 방어적 복사본을 만들어야 한다.

변경 불가능 객체의 장/단점

장점

변경 불가능 객체는 단순하다. 생성될 때 부여된 한가지 상태만 갖기 때문에 생성자가 불변식을 확실히 따른다면, 해당 객체는 불변식을 절대 어기지 않는다.

변경 불가능 객체는 스레드에 안전하다. 어떤동기화도 필요없다. 그렇기 떄문에 private static final 등을 이용하여 자유롭게 공유할 수 있다. 

변경 불가능 객체는 다른 객체의 구성요로도 훌륭하다. 불변이기 때문에 맵과 집합의 키로 유용하다.

단점

값마다 별도의 객체를 만들어야 한다. 따라서 객체 생성 비용이 높을 가능성이 있다.


요약

변경 가능한 클래스로 만들 타당한 이유가 없다면, 반드시 변경 불가능 클래스로 만들어야 하며, 이렇게 하기 힘들다면 변경 가능성을 최대한 제한하여야 한다. 특별한 이유가 없다면 모든 필드는 final로 선언하며, 생성자 이외의 public 초기화 메서드나 정적 팩터리 메서드를 제공하면 안된다.


+ Recent posts