본문 바로가기
Java

[EffectiveJava] Item17 변경 가능성을 최소하라

by 신입같은 3년차 2021. 1. 6.
728x90

불변클래스란(Immutable Class) ?
해당 객체의 내부적인 값들을 변경할 수 없는 클래스를 의미한다. 불변 클래스는 해당 객체가 파괴되는 순간까지 절대 달라지지 않는다.
불변 클래스는 가변 클래스보다 설계하고 구현하기 쉽고, 사이드 이펙트로부터 안전하다.

클래스를 불변으로 만드는데 필요한 5가지 규칙이 있다.

1. 객체의 상태를 변경하는 메서드를 제공하지 않는데.
2. 클래스를 확장할 수 없도록 한다.(class 에 final 선언, 다른방법도 있음)
3. 모든 필드들을 final 로 선언한다.
4. 모든 필드들을 private 접근제한자로 선언한다.
5. 자신 외에는 내부의 가변 컴포넌트에 접근할 수 없도록 한다.

public final class Calculator { 
private final double a; 
    private final double b; 

    public Calculator(double a, double b) { 
     this.a = a; 
        this.b = b; 
    } 

    public Calculator plus(Caculator calculator) { 
     new Calculator(a + calculator.a, b + calculator.b); 
    } 
} 

다음 예제는 대략적인 느낌을 맞추기 위해 대충 작성한 코드입니다.

해당 코드에서 주목해야할 코드는 plus라는 메서드가 자신의 필드를 수정하지 않고 새로운 객체를 생성하여 반환한다는 점입니다.

위와 같이 피연산자에 함수를 적용해 해당 결과를 반환하지만, 피연산자 자체는 그대로인 프로그래밍 패턴을 함수형 프로그래밍이라고 한다.

위와 같이 함수형 프로그래밍으로 작성한다면 다음과 같은 이점을 얻을 수 있다.


*불변 객체는 단순하다 *
불변 객체는 생성된 시점의 상태를 파괴될때까지 그대로 유지한다.

모든 생성자가 불변하다는것을 보장할 수 있다면 해당 클래스를 사용하는 다른 개발자들에게도 영원히 불변하다는것을 보장할 수 있다. 하지만 가변 객체는 원하지 않는 사이드 이펙트를 일으킬 가능성이 크다.


** 불변 객체는 스레드에 대해 안전하여 따로 동기화 할 필요가 없다. **
여러 스레드가 동시에 사용해도 불변 객체이기 때문에 다른 스레드에 영향을 주지 않아 안전하게 공유하고 사용할 수 있다.


** 불변 클래스는 정적 팩터리를 제공할 수 있다. **

불변 클래스는 자주 사용하는 인스턴스를 캐싱하여 중복생성되지 않게 정적 팩터리 처럼 제공할 수 있다.


** 값이 바뀌지 않는 구성요소들로 이루어져 있기 때문에 아무리 구조가 복잡하더라도 불변하다는것을 보장하는것이 쉽기 때문이다. **


** 불변 객체는 그 자체로 실패 원자성을 제공한다 **
Item 76에서 확인하겠지만 상태가 절대 변하지 않는 불변성을 제공하기 때문에 잠깐이라도 불일치 상태에 빠질 가능성이 없다.


불변객체의 단점

그렇다면 불변객체의 단점은 뭐가있을지 생각해보면 다음과 같다
값이 하나라도 다를경우 반드시 독립된 객체로 만들어야 한다 값의 가짓수가 많다면 이들을 모두 만드는데 들어가는 비용이 더 크다...

정리해서 중요한점만 보자면 다음과 같다.

따라서 모든 클래스를 불변으로 만들 수는 없기 때문에 클래스라도 변경 가능한 부분을 최소한으로 줄이는것이 좋다. 따라서 꼭 변경해야하는 필드릴 제외한 나머지 필드들을 모두 private final 로 선언하자.

생성자는 불변식 설정이 완료된 완벽한 상태의 객체를 반환해야한다.

728x90
반응형

댓글