아이템17. 변경 가능성을 최소화하라
- 불변 클래스란 그 인스턴스와 내부 값을 수정할 수 없는 클래스다. 불변 인스턴스에 간직된 정보는 고정되어 객체가 파괴되는 순간까지 절대 달라지지 않는다.
불변클래스를 만들기 위한 다섯가지 규칙
- 객체의 상태를 변경하는 메서드(변경자)를 제공하지 않는다.
- 클래스를 확장할 수 없도록 한다.
- 모든 필드를 final로 선언한다.
- 모든 필드를 private으로 선언한다.
- 자신 외에는 내부의 가변 컴포넌트에 접근할 수 없도록 한다.
- 함수형 프로그래밍 : 피연산자에 함수를 적용해 결과를 반환하지만, 피연산자 자체는 그대로인 프로그래밍 패턴
- 메서드 이름을 동사형(ex.add) 대신 전치사형(ex.plus)로 사용하여 강조한다.
- 함수형 프로그래밍을 사용하면 불변이 되는 영역의 비율을 높아지는 장점을 누릴 수 있다.
- 절차적/명령형 프로그래밍 : 메서드에서 피연산자인 자신을 수정해 자신의 상태가 변하게 된다.
불변 객체의 특징
- 불변 객체는 단순하다 : 불변객체는 생성시점부터 파괴될때까지 상태를 그대로 간직한다.
- 불변 객체는 근본적으로 스레드 안전하여 따로 동기화할 필요가 없다.
- 불변 객체는 안심하고 공유할 수 있다.
- 불변 객체는 자유롭게 공유할 수 있음은 물론, 불변 객체끼리는 내부 데이터를 공유할 수 있다.
- 객체를 만들 때 다른 불변 객체들을 구성요소로 사용하면 이점이 많다.
- 불변 객체는 그 자체로 실패원자성을 제공한다 : 실패원자성? 메서드에서 예외가 발생한 후에도 그 객체는 여전히 호출전과 똑같은 유효한 상태.
- 상태가 절대 변하지 않으니 잠깐이라도 불일치 상태에 빠질 가능성이 없다.
불변 클래스의 단점
- 값이 조금이라도 다르면 반드시 독립된 객체로 만들어야 한다. ex. 백만 비트짜리 BigInteger에서 비트 하나를 바꿔야 한다면 새로운 객체로 만들어야 한다.
- 이러한 문제를 해결하기 위해서는 다단계연산들을 예측하여 기본 기능으로 제공하는 방법이 있다.
- 가변 동반 클래스
불변 클래스로 만드는 또다른 설계 방법 : 상속하지 못하게 만들자.
- final클래스로 선언하는 것도 맞지만, 더 유연한 방법이 있다.
- 모든 생성자를 private 혹은 package-private으로 만들고 public 정적 팩터리를 제공하는 방법이다.
public class Complex{
private final double re;
private final double im;
private Complex(double re, double im){
this.re= re;
this.im= im;
}
public static Complex valueOf(double re, double im){
return new Complex(re,im);
}
}
정리
클래스는 꼭 필요한 경우가 아니라면 불변이여야 한다. 모든 클래스를 불변으로 만들수는 없지만, 불변으로 만들수 없는 클래스라도 변경할 수 있는 부분을 최소한으로 줄이자. 다른 합당한 이유가 없다면 모든 필드는 private final이여야 한다. 생성자는 불변식 설정이 모두 완료된, 초기화가 완벽히 끝난 상태의 객체를 생성해야 한다.
'Algorithm Study' 카테고리의 다른 글
[프로그래머스] 양궁대회(level2) / JAVA, DFS (0) | 2022.07.23 |
---|---|
아이템18. 상속보다는 컴포지션을 사용하라 (0) | 2022.06.24 |
아이템16. public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라 (0) | 2022.06.24 |
아이템15. 클래스와 멤버의 접근 권한을 최소화하라 (0) | 2022.06.24 |
[스프링/Spring] Port 8080 is already in use 에러 해결 방법 (Mac) (0) | 2022.06.17 |