인프런 커뮤니티 질문&답변

백엔드해야지님의 프로필 이미지

작성한 질문수

스프링 핵심 원리 - 기본편

5. 싱글톤 컨테이너 - 싱글톤 패턴의 단점 부분 질문입니다.

24.03.08 09:06 작성

·

242

0

안녕하세요,

  1. 싱글톤 컨테이너 - 싱글톤 패턴의 단점 부분에서 질문이 있습니다.

     

스프링 컨테이너가 빈을 싱글톤으로 관리하는 부분에 대해 설명하시는 강의이므로 ["컨테이너에 의한 싱글톤"과 비교하여 "일반 싱글톤 패턴"이 갖는 단점]이라는 측면으로 이해하려 합니다.

  • 의존관계상 클라이언트가 구체 클래스에 의존한다 -> DIP를 위반한다. / 클라이언트가 구체 클래스에 의존해서 OCP 원칙을 위반할 가능성이 높다.

    • 다른 질문글들을 찾아보니 이 내용은 "컨테이너를 사용하지 않을 경우 싱글톤이 아닌 일반적인 구체 클래스를 클라이언트에서 직접 new 하듯이 클라이언트에서 구체적인 싱글톤 클래스의 getInstance를 호출해야한다"는 점에서 DIP를 위반한다는 내용으로 이해됩니다. 그러면 이 단점은 컨테이너를 사용하지 않을 경우 싱글톤 클래스나 싱글톤이 아닌 클래스나 마찬가지로 갖는 단점인데 싱글톤 패턴의 단점이라고 표현하신 점에서 제가 이해하지못한 차이가 있는지 궁금합니다.

  • 테스트하기 어렵다. / 내부 속성을 변경하거나 초기화 하기 어렵다.

    • 컨테이너를 사용하면 config에서 의존관계의 구체클래스만 변경하며 객체의 속성 변경이 용이하지만 직접 구현한 싱글톤 패턴은 이미 생성된 static 객체가 존재하므로 내부를 변경해야한다면 1) 싱글톤 클래스의 코드를 고치거나 2) 클라이언트 또는 테스트 코드에서 수정자 등을 이용해야하므로 내부 속성 변경이 번거롭고 따라서 여러 케이스로 테스트가 어렵다는 의미일까요?

  • 결론적으로 유연성이 떨어진다. ("DI가 어렵다, 구체 클래스의 getInstance를 다 해줘야 한다, ...")

    • 이 부분도 컨테이너가 없을 경우 일반 클래스, 싱글톤 클래스가 갖는 단점이라 생각되는데 싱글톤의 단점이라 표현하신 점에서 제가 이해하지 못한 부분이 있는지 궁금합니다.

       

 

감사합니다.

답변 2

0

김영한님의 프로필 이미지
김영한
지식공유자

2024. 03. 11. 20:03

안녕하세요. 백엔드해야지님

싱글톤을 직접 사용할 경우, 보통은 DI를 하지 않고 구체 클래스를 바로 의존하도록 사용합니다.

왜냐하면 이런 의도로 public static의 getInstance() 메서드를 제공하는 것이지요.

따라서 구체클래스.getInstance()를 호출하는 방식을 주로 사용합니다.

궁금해하시는 문제들은 모두 여기서 파생되는 문제입니다 :)

감사합니다.

0

인프런 AI 인턴님의 프로필 이미지

2024. 03. 10. 09:11

안녕하세요, 인프런 AI 인턴입니다.

백엔드해야지님의 질문에 대해 답변드리겠습니다.

  • 일반적인 싱글톤 패턴의 경우, 클라이언트 코드가 싱글톤 인스턴스를 가져오기 위해 싱글톤 클래스의 getInstance 메서드를 직접 호출해야 합니다. 이것은 클라이언트 코드가 구체 클래스에 직접 의존하게 만들어 DIP(의존 역전 원칙)를 위반하고, 결과적으로 OCP(개방-폐쇄 원칙) 또한 위반할 가능성을 높입니다. 즉, 이 단점은 싱글톤 패턴이 갖는 고유의 문제입니다. 스프링 컨테이너 같은 IoC 컨테이너를 사용한다면 이러한 문제를 추상화를 통해 해결할 수 있습니다.

  • 싱글톤 객체는 전역적으로 하나의 인스턴스만을 유지하므로 상태를 변경하거나 초기화하기 어려운 문제가 있습니다. 본래 구현된 싱글톤 패턴은 코드 내에서 싱글톤 인스턴스의 상태를 변경하려 할 때, 프로그램 전반에 걸쳐 영향을 미칠 수 있는 부분을 신중하게 관리해야 하며, 특히 테스트 환경에서는 독립적인 테스트가 어렵습니다. 스프링 컨테이너를 사용하면, 설정 변경을 통해 객체의 속성을 쉽게 변경할 수 있습니다.

  • 마지막으로, 싱글톤 패턴은 자체적으로 DI를 구현하기 어렵습니다. 인스턴스화 로직이 싱글톤 클래스 안에 고정되어 있기 때문에 다른 구현체로 교체하기가 번거롭거나 때로는 불가능할 수 있습니다. 이러한 구조는 코드의 유연성을 떨어뜨리며, 컨테이너를 사용하지 않는 경우라도 마찬가지로 이러한 단점을 갖게 됩니다. 그러나 스프링 컨테이너를 이용하면, IoC를 통해 객체를 관리함으로써 이러한 단점을 보완할 수 있습니다.

감사합니다.