아이템 17 : 변경 가능성을 최소화하라
불변 클래스란 간단히 말해 그 인스턴스의 내부 값을 수정할 수 없는 클래스다.
클래스를 불변으로 만들려면 다음 다섯 가지 규칙을 따르면 된다.
- 객체의 상태를 변경하는 메서드를 제공하지 않는다.
- 클래스를 확장할 수 없도록 한다.
- 모든 필드를 final로 선언한다.
- 모든 필드를 private으로 선언한다.
- 자신 외에는 내부의 가변 컴포넌트에 접근할 수 없도록 한다.
불변 객체는 단순하다. 불변 객체는 생성된 시점의 상태를 파괴될 때까지 그대로 간직한다.
또한 불변 객체는 근복적으로 스레드 안전하여 따로 동기화할 필요가 없다.
불변 객체에 대해서는 그 어떤 스레드도 다른 스레드에 영향을 줄 수 없으니 불변 객체는 안심하고 공유할 수 있다.
불변 객체는 자유롭게 공유할 수 있음은 물론, 불변 객체끼리는 내부 데이터를 공유할 수 있다.
객체를 만들 때 다른 불변 객체들을 구성요소로 사용하면 이점이 많다. 값이 바뀌지 않는 구성요소들로 사용하면 이점이 많다. 값이 바뀌지 않는 구성요소들로 이뤄진 객체라면 그 구조가 아무리 복잡하더라도 불변식을 유지하기 훨씬 수월하기 때문이다.
불변 객체는 그 자체로 실패 원자성을 제공한다. 상태가 절대 변하지 않으니 잠깐이라도 불일치 상태에 빠질 가능성이 없다.
불변 클래스에도 단점은 있다. 값이 다르면 반드시 독립된 객체로 만들어야 한다는 것이다.
게터가 있다고 해서 무조건 세터를 만들지는 말자. 클래스는 꼭 필요한 경우가 아니라면 불변이어야 한다. 불변 클래스는 장점이 많으며, 단점이라곤 특정 상황에서의 잠재적 성능 저하뿐이다.
한편, 모든 클래스를 불변으로 만들 수는 없다. 불변으로 만들 수 없는 클래스라도 변경할 수 있는 부분을 최소한으로 줄이자. 객체가 가질 수 있는 상태의 수를 줄이면 그 객체를 예측하기 쉬워지고 오류가 생길 가능성이 줄어든다. 그러니 꼭 변경해야 할 필드를 뺀 나머지 모두를 final로 선언하자.
핵심 정리
다른 합당한 이유가 없다면 모든 필드는 private final이어야 한다. 생성자는 불변식 설정이 모두 완료된, 초기화가 완벽히 끝난 상태의 객체를 생성해야 한다. 확실한 이유가 없다면 생성자와 정적 팩터리 외에는 그 어떤 초기화 메서드도 public으로 제공해서는 안 된다.
'언어 > JAVA' 카테고리의 다른 글
[Effective Java] 상속을 고려해 설계하고 문서화하라. 그렇지 않았다면 상속을 금지하라 (0) | 2020.03.18 |
---|---|
[Effective Java] 상속보다는 컴포지션을 사용하라 (0) | 2020.03.17 |
[Effective Java] public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라 (0) | 2020.03.16 |
[Effective Java] 클래스와 멤버의 접근 권한을 최소화하라 (0) | 2020.03.16 |
[Effective Java] Comparable을 구현할지 고려하라 (0) | 2020.03.15 |