Adventure Time - Lady Rainicorn [아이템17] 변경 가능성을 최소화하라
본문 바로가기
🤓 스터디/이펙티브 자바

[아이템17] 변경 가능성을 최소화하라

by 강켄트 2023. 3. 24.

책에서 말하고 있는 변경 가능성을 최소화하려면 불변 클래스를 만들어야하는데 

불변 클래스란 인스턴스 내부 값을 수정할 수 없는 클래스를 말하고,

객체가 소멸되기 전까지 절대 달라지지 않는 것이다.

 

왜 변경 가능성을 최소화해야할까? 

불변 클래스와 같이 변경 가능성이 불변이 되면 값이 고정되니까 설계가 쉬워지고

오류 발생 소지도 적고 훨씬 안전하기 때문!

 

불변 클래스를 만드는 규칙 

  • 객체의 상태를 변경하는 메서드(변경자)를 제공 X
  • 클래스 확장 X
  • 모든 필드를 final로 선언
  • 모든 필드를 private으로 선언
  • 자신 외에는 내부의 가변 컴포넌트에 접근 X

클래스를 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);
    }
}

 

불변 클래스와 불변 객체는 어떻게 다를까

불변 클래스의 객체는 근본적으로 스레드 안전하기 때문에 안심하고 공유할 수 있다. 

따라서

불변 클래스라면 한번 만든 인스턴스를 최대한 재활용하면 좋다. (StringBuilder, StringBuffer)

불변 객체는 그 자체로 실패 원자성을 제공한다.

 

실패 원자성(failure atomicity)이란?
메서드에서 예외가 발생한 후에도 그 객체는 여전히 메서드 호출 전과 똑같은 유효한 상태여야 한다.

public class BigInteger extends Number implements Comparable<BigInteger> {
    final int signum;
    final int[] mag;
    ...
    public BigInteger negate() {
        return new BigInteger(this.mag, -this.signum);
    }
    ...
}

 

 

ps

클래스는 꼭 필용한 경우가 아니면 불변으로 만들자

다른 이유가 없다면 클래스의 모든 필드는 private final로 만들자

댓글