저는 스프링을 사용하면서 스스로 싱글톤패턴 코드를 짜본적이 없습니다.
하지만
프레임워크를 사용하지 않고, 순수 자바 코드로 비즈니스 코드구현 과제를 하던 중
결국 싱글톤 패턴을 이용하여 DI컨테이너(동시에 OCP컨테이너)를 만들어야 했는데요.
객체지향적으로 코드를 짜던 도중, 이때 싱글톤 패턴의 고질적인 문제에 봉착하게 됩니다.
아래 코드에서 --> 싱글톤으로 바꿔야 되는 상황
결국 싱글톤코드를 품은 객체도 구체 클래스에 의존하게 됩니다.
이러면 DIP를 위반하게 되죠..
이렇게 구체 클래스에 의존하게 되면 또 OCP를 어기게 됩니다.
DIP,OCP를 만족시키려면 클라이언트 구체 클래스를 제어하는 책임을 져야 하는데,
이러면 또 클라이언트 객체는 DIP,OCP를 어기게 되는 체인성 문제가 이어집니다.
결국 순수 자바 코드로 짤때는 한 클라이언트 객체가 많은 책임을 지게 됩니다.
이런 문제가 있었습니다.
또한 싱글톤 객체의 메서드를 사용하는 클래스마다 높은 결합도가 발생하게 됩니다.
이는 싱글톤 객체를 수정하면 싱글톤 객체와 결합한 모든 코드들을 테스트 해봐야하는 단점이 있습니다.
단위 테스트를 할때, 싱글톤 패턴은 테스트하기 어렵습니다.
단위 테스트할 때 생성 검증을 해야 하는데, 이미 싱글톤 내부에서 생성해 놓았기 때문입니다.
의존관계상 클라이언트가 구체 클래스에 의존한다 --> DIP를 위반한다.
클라이언트가 구체 클래스에 의존해서 OCP 원칙을 위반할 가능성이 높다.
- 순수 자바코드의 한계인 것 같다. 결국 어떤 클라이언트 객체가 모든 책임을 맡아야 하기 때문
테스트하기 어렵다.
무상태로 해결해야 한다 - 특정 클라이언트가 값을 변경할 수 있는 필드가 있으면 안된다. 그리고 공유 값을 설정하면 정말 큰 장애가 발생할 수 있다.
누군가는 싱글톤 객체의 내부 구체 클래스들을 제어해줘야 합니다.
즉,싱글톤 객체도 제어의 역전이 되게 누군가 구체 클래스를 아는 책임을 맡아줘야 합니다.
이때 프레임워크(스프링)이 등장합니다.
스프링의 도움(CGLIB 기술이용-싱글톤 대체화,@Component+@Autowired - 컨테이너에 자동등록 ... )을 받아 위와 같은 문제점을 보완하면서도 싱글톤 패턴의 장점을 누릴 수 있도록 이용할 수 있습니다.
조금 더 추가 기능을 말해보면
빈 컨테이너(Ioc 컨테이너)가 객체들의 Scope를 관리해줍니다.
그리고
덜 완성된 클래스를 단위 테스트할 때, 테스팅을 도와줍니다.
유투브 - 제대로 이해하는 싱글톤패턴
찾아본 블로그1
찾아본 블로그2
inflearn - 스프링 핵심 원리(기본 편)