Item 15. 변경 가능성을 최소화하라
Immutable Class
ㄴ String, 기본 자료형 클래스, BigInteger, BigDecimal 등
Immutable Class 구현 방법
- 객체 상태를 변경하는 메서드를 제공하지 않는다
- 계승할수 없도록 한다 => final Class 선언
- 모든 필드를 final로 선언 => 새로 생성된 객체에 대한 참조가 동기화없이 다른 스레드로 전달되어도 안전하다.
- 모든 필드를 private로 선언한다. => 클라이언트가 필드가 참조하는 변경 가능 객체를 직접 수정하는 일을 막을 수 있다
- 변경 가능 컴포넌트에 대한 독점적 접근권을 보장한다 => 클래스에 포함된 변경 가능 객체에 대한 참조를 클라이언트는 획득 할 수 없어야한다
101 ex this 객체를 변경하는 대신 새로운 Complex 객체를 만들어서 반환
- 함수형 접근법 => 변경 불가능성을 보장 )) 피연산자를 변경하는 대신, 연산을 적용한 결과를 새롭게 만들어 반환
- 절차적 or 명령형 접근법은 피연산자에 일정한 절차를 적용하여 그 상태를 바꿈
Immutable Class 장점
- 변경 불가능 객체는 단순하다, 생성 될때 부여된 한가지 상태만 갖는다
변경 불가능 객체는 스레드에 안전할 수 밖에 없다.
ㄴ 어떤 동기화도 필요없으며, 여러 스레드가 동시에 사용해도 상태가 훼손될 일이 없다
- 변경 불가능한 객체는 자유롭게 공유 할 수 있다 => 방어직 복사본을 만들 필요가 없다
public static final Complex ZERO = new Complex(0,0);
- 변경 불가능한 객체는 그 내부도 공유할 수 있다
- 변경 불가능한 객체는 다른 객체의 구성요소로도 훌륭하다
Immutable Class 단점
- 변경 불가능 객체의 유일한 단점은 값마다 별도의 객체를 만들어야 한다는 점 => 객체 생성 비용이 높을 가능성이 있다
Immutable Class 대안적 설계법
- 클래스를 final 선언 -> 모든 생성자의 private나 package-private로 선언하고 public 생성자 대신 pubilc 정적 팩터리를 제공하는 것
- 모든 get 메서드 마다 그에 대응하는 set 메서드를 두는 것은 피해야한다.
- 변경 가능한 클래스로 만들 타당한 이유가 없다면, 반드시 변경 불가능 클래스로 만들어야한다.
- 변경 불가능한 클래스로 만들 수 없다면, 변경 가능성을 최대한 제한하라.
- 특별한 이유가 없다면 모든 필드는 final로 선언하라
- 생성자는 완전히 초기화가 끝나서 모든 불변식이 만족되는 객체를 만들어야 한다.