싱글톤 패턴 (singleton pattern)

곰겜·2025년 9월 9일

Design Pattern

목록 보기
1/2
post-thumbnail

목차

  1. 싱글톤 패턴이란?
  2. 자바에서 싱글톤 패턴 사용 예시
  3. 싱글톤 패턴의 장단점
  4. 의존성 주입

싱글톤 패턴이란?

하나의 클래스에 오직 하나의 인스턴스만 가지는 패턴.
하나의 클래스를 기반으로 단 하나의 인스턴스를 만들어 이를 기반으로 로직을 만드는 데 쓴다.

자바에서 싱글톤 패턴

class Singleton {
    /*
    - Singleton 클래스가 처음 로딩될 때는 이 내부 클래스가 로딩되지 않음
    - getInstance() 메서드가 처음 호출될 때 singleInstanceHolder가 로딩되면서
      INSTANCE가 생성됨 → Lazy Initialization(지연 초기화) 보장
    */
    private static class singleInstanceHolder {
        private static final Singleton INSTANCE = new Singleton(); // 단 하나의 인스턴스
    }
        
    /* 
    외부에서 싱글톤 객체에 접근할 수 있는 유일한 메서드
    - 호출 시 내부 클래스가 처음 로딩되며 INSTANCE가 생성됨
    - 이후에는 동일한 INSTANCE를 반환 
    */
    public static Singleton getInstance() {
        return singleInstanceHolder.INSTANCE;
    }
}

public class Main {
    public static void main(String[] args) {
        // getInstance()를 통해 인스턴스를 두 번 가져옴
        Singleton a = Singleton.getInstance();
        Singleton b = Singleton.getInstance();
    
        // 두 객체의 해시코드 출력
        // -> 같은 객체이므로 해시코드 값이 동일하게 출력됨
        System.out.println(a.hashCode()); // 예: 929338653
        System.out.println(b.hashCode()); // 동일한 값 출력
    
        // 동일한 인스턴스를 참조하는지 비교
        if(a == b) {
            System.out.println(true); // true → 같은 객체임을 의미
        }
    }
}
 

싱글톤 패턴의 장단점

장점

  • 생성 비용 절약: 무거운 객체를 매번 만들지 않아도 됩니다.

  • 접근 일관성: 전역적으로 동일 인스턴스를 사용합니다.

  • 간단한 사용성: Singleton.getInstance()로 즉시 접근 가능합니다.

단점

  • 결합도 상승(전역 의존): 여러 모듈이 하나의 전역 인스턴스에 기대면 변경 파급이 커집니다.

  • 테스트 격리 어려움: 단위 테스트는 서로 영향을 주지 않아야 해서, 어떤 순서로 돌려도 결과가 같아야 합니다.
    그런데 싱글톤은 프로그램 전체가 하나의 객체를 함께 쓰기 때문에, 테스트마다 새로운 상태로 시작하기가 어렵습니다. 그래서 앞선 테스트에서 바뀐 값이 그대로 남아 다음 테스트에 영향을 줄 수 있습니다.

    비유: 하나뿐인 화이트보드를 여러 명이 번갈아 쓰면, 매번 깨끗이 지우지 않는 한 이전 낙서가 다음 사람에게 남는 것과 같습니다.

의존성 주입

싱글톤 패턴은 사용하기 쉽지만 모듈 간의 결합을 강하게 만들 수 있다는 단점이 있다. 이때 DI을 통해 모듈 간의 결합을 조금 더 느슨하게 만들어 해결할 수 있다.

메인 모듈이 직접 하위 모듈에 의존성을 주기보다 중간에 의존성 주입자가 이 부분을 가로채 메인 모듈이 간접적으로 의존성 주입하는 방식

메인 모듈은 하위 모듈에 대한 의존성이 떨어지게 됩니다.

의존성 주입의 장점

모듈들을 쉽게 교체 할 수 있는 구조가 되어, 테스트가 쉬워지고, 모듈 간의 관계들이 조금 더 명확해집니다.

의존성 주입의 단점

모듈들이 더욱더 분리 되므로 클래스 수가 늘어나 복잡성이 증가될 수 있습니다.

profile
Python->Java,Kotlin->Rust->Java,Kotlin

0개의 댓글