SSAFY11th-book-study / book-study

SSAFY 11기 6반의 '토비의 스프링 스터디'
0 stars 0 forks source link

[1.6.2] 싱글톤과 오브젝트의 상태 #10

Closed sootudio closed 7 months ago

sootudio commented 7 months ago

1.6.2 장에서 싱글톤의 오브젝트에 대해서 '읽기전용의 값이라면 초기화 시점에서 인스턴스 변수에 저장해두고 공유하는 것은 아무 문제가 없다' 라고 나와 있습니다.

그런데 제가 생각했을 때는 싱글톤 패턴을 사용할 때도 읽기전용의 값을 사용하거나 변경 불가능한 객체를 관리하는 경우에는 추가적인 동시성 관리를 할 필요가 없기 때문에 스프링의 싱글톤을 사용하는 것과 별 차이가 없다는 생각이 들었습니다.

때문에 위의 상황처럼 읽기전용의 데이터를 다루거나 변경 불가능한 객체를 관리할 때, 스프링 싱글톤 Bean을 사용하는 것이 싱글톤 패턴을 사용하는 것에 비해 더 장점이 있는지, 있다면 어떤 것일지 궁금합니다.

limjongheok commented 7 months ago

우선 책에서 읽기 전용 값은

private  ConnectionMaker connectionMaker;

다음과 같이 connectionMaker 를 가리키는데 해당 connectionMaker 는

  public UserDao(ConnectionMaker connectionMaker){
        this.connectionMaker = connectionMaker;
    }

다음과 같이 생성자 주입을 통해 얻어 오는 값입니다. 이는 스프링 빈을 사용하여 싱글톤이 아닌 자바? 객체지향 형식으로 사용할 수 있기 때문에 가능한 형식입니다. 기존 싱글톤에서는 이러한 생성자 주입 형식을 사용할 수 없습니다. 또한 책 표현 처럼 connectionMaker 는

@Bean
    public ConnectionMaker connectionMaker() {
       return new DConnectionMaker();
    }
   @Bean
    public UserDao userDao(){
       return new UserDao(connectionMaker());
   }

싱글톤으로 관리하여 넣어주기 때문에 읽기 전용 값이 될 수 있었던 것입니다.

gmelon commented 7 months ago

저도 단순히 인스턴스 변수를 읽기 전용으로 사용한다면 스프링 컨테이너의 도움을 받는 것과 일반적인 싱글톤 패턴의 구현을 사용하는 것의 차이가 없다고 생각합니다.

다만 스프링을 사용했을 때의 장점이라면 종혁님이 말씀해주신 것처럼 싱글턴 + 생성자 주입이 가능해지기 때문에 아래와 같이 인스턴스 변수를 final로 선언할 수 있는 점이라고 생각합니다.

public class UserDao {
    private final ConnectionMaker connectionMaker;

    // 생성자

}

위와 같이 final로 선언하면 읽기 전용 이라는 것을 명시해주고 컴파일러가 변경되지 않음을 보장해주기 때문에 더욱 안전하게 사용할 수 있다고 생각합니다.

일반적인 싱글톤 구현으로는 (외부에서 주입이 필요한 값이라면) 생성 시점에 인스턴스 변수를 할당할 수 없기 때문에 final이 아닌 일반 변수로 선언해야 해서 (읽기 전용으로 사용되어야 하지만) 언제든지 값이 변경될 위험에 처해있다고 생각합니다.