253. 싱글톤 (Singleton) - 오직 하나의 인스턴스 전역 변수 메모리 절약 데이터베이스 커넥션 생성 패턴 객체지향

핵심 인사이트: (가장 유명하고 만만한 디자인 패턴) 쇼핑몰에 손님 1만 명이 접속했다. 손님 1명이 물건 하나 살 때마다 "DB 접속용 쇳덩어리 기계 객체(커넥션)"를 1개씩 new 로 새로 찍어냈다. 1만 명이 클릭하니 DB 접속 객체가 1만 개가 생겨서 서버 메모리(RAM)가 펑 터져버렸다! 사장님이 극대노했다. "야 ㅆㅂ!! DB 접속하는 기계는 똑같은 기능만 하는데 왜 1만 개나 새로 찍어내서 메모리를 태워!! 프로그램 전체, 아니 우주 전체를 통틀어서 그 DB 접속 기계(객체)는 하늘이 두 쪽 나도 딱 '1개'만 만들어(생성자 private 차단)!! 그리고 그 1개를 금고에 꽁꽁 모셔둔 다음에, 1만 명이 필요할 때마다 무조건 그 금고 안에 있는 '유일한 1개'를 돌려쓰기(공유)하게 만들어라!!" 무한 복제를 사형시키고 우주에서 오직 단 1개의 영혼만 남기는 극강의 메모리 짠돌이 마술, 싱글톤(Singleton) 패턴이다.

Ⅰ. new 무한 복제의 메모리 대참사

  • 객체지향에서 클래스를 붕어빵 틀로 쓰면, new를 할 때마다 메모리에 새로운 붕어빵이 계속 쌓입니다.
  • 문제점: 하지만 세상에는 여러 개가 있으면 안 되는 놈들이 있습니다.
    • 예시: 데이터베이스 커넥션 풀, 쓰레드 풀, 윈도우의 '설정(Setting) 관리자'.
    • 이런 놈들을 10명이 호출한다고 10개를 찍어내면, 메모리(RAM)가 낭비될 뿐만 아니라 10개 객체가 서로 다른 설정을 가지게 되어 시스템 상태(데이터)가 뒤죽박죽 꼬여버립니다.

Ⅱ. 싱글톤 패턴 (Singleton Pattern)의 개념 🌟

  • 개념: GoF 생성 패턴 중 하나로, 어떤 클래스가 애플리케이션(우주) 전체에서 오직 '단 하나의 인스턴스(객체 1개)'만 생성되도록 강제로 보장하고, 어디서든 그 유일한 객체에 전역적으로 접근할 수 있는 방법을 제공하는 패턴입니다.

Ⅲ. 싱글톤의 완벽한 밀실 구현법 (코드 3대장) 🌟 핵심 🌟

어떻게 다른 개발자가 new를 못 치게 막을 수 있을까요?

  1. 생성자의 모가지를 자른다 (private 생성자):
    • 클래스 안의 생성자 함수 앞에 무조건 private을 박아버립니다.
    • 이제 바깥에서 다른 개발자가 new Singleton()을 치는 순간 자바 컴파일러가 쌍욕을 하며 빨간 줄(에러)을 긋습니다. "야! 밖에서 붕어빵 못 구워!"
  2. 금고 안에서 자기가 스스로 1개 굽기 (private static 변수):
    • 밖에서 못 구우니, 클래스 내부 안쪽에서 자기가 스스로 자기 자신을 딱 1개 구워놓고(new) 금고(Static 메모리) 안에 꽁꽁 숨겨둡니다.
  3. 유일한 배급 창구 뚫기 (public static getInstance() 함수):
    • 밖에서 객체가 필요한 놈들은 new를 못 치니, 무조건 이 배급 창구 함수를 호출해야만 합니다.
    • getInstance() 함수는 "어? 너 왔냐? 아까 내가 만들어둔 금고 속의 그 유일한 1개, 그거 던져줄게 써라!" 하고 항상 똑같은 1개의 주소값(참조)만 반환해 줍니다. 1만 명이 와도 똑같은 주소값 1개만 돌려받아 다 같이 씁니다.

Ⅳ. 핏빛 트레이드오프 (싱글톤의 악몽)

면접관들이 제일 좋아하는 질문입니다. "싱글톤이 무조건 좋나요?" 절대 아닙니다!

  • 장점: 메모리 낭비가 0%고, 데이터 공유(전역 상태)가 미치도록 쉽습니다.
  • 치명적 단점 (객체지향의 적) 🌟:
    • 결국 싱글톤은 예쁘게 포장한 '전역 변수(Global Variable)' 쓰레기에 불과합니다. 1만 개의 클래스가 이 싱글톤 1개를 다 같이 바라보고 얽혀버리기 때문에(결합도 대폭발), 나중에 싱글톤을 고치면 1만 개의 클래스가 도미노처럼 다 에러가 터집니다.
    • 게다가 219번 동시성 문제! 1만 명이 싱글톤 1개에 동시에 데이터를 쓰려고(Write) 달려들면 데이터 모순이 터지므로, 안에 자물쇠(Lock/Sync)를 달아야 하는데 이게 또 병목(속도 저하)의 원흉이 됩니다. 그래서 현대의 스프링(Spring) 프레임워크는 개발자가 직접 짜는 더러운 싱글톤을 버리고, 자기가 알아서 컨테이너 안에서 1개로 관리(DI)해 줍니다.

📢 섹션 요약 비유: 싱글톤(Singleton) 패턴은 전교생 1,000명이 있는 학교의 **'유일한 복사기 1대 사용 룰'**입니다. 멍청한 학교(new 남발)는 학생 1,000명이 복사할 때마다 각자 자기 책상에 100만 원짜리 복사기를 1대씩 새로 사서(메모리 낭비) 올려놓고 씁니다. 교장 선생님(아키텍트)이 극대노하여 학교의 모든 복사기를 때려 부수고(private 생성자로 밖에서 생성 금지), 오직 교무실 구석 금고에 **'황금 복사기 딱 1대(private static instance)'**만 놔둡니다. 그리고 교무실 창문(getInstance() 메서드)을 딱 하나 엽니다. 학생 1,000명이 복사가 필요할 땐 자기가 복사기를 살 수 없으므로 무조건 교무실 창문으로 와야 합니다. 교무실 당번은 매번 새로운 복사기를 주는 게 아니라, "저기 구석에 있는 저 황금 복사기 1대로 다 같이 쓰고 제자리에 둬!" 라며 유일한 복사기 1대의 위치(참조값)만 똑같이 알려줍니다. 학교의 돈(메모리)은 극단적으로 절약되지만, 기말고사 때 1,000명이 동시에 복사기를 쓰겠다고 몰려들면 폭동(동시성 에러 및 병목)이 일어나는 극단적인 원탑 독재 인프라 패턴입니다.