Menu
Coddy logo textTech

싱글톤 패턴

Coddy Java 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 87개 중 65번째.

싱글톤 패턴(Singleton Pattern)은 애플리케이션 전반에서 클래스의 인스턴스가 오직 하나만 존재하도록 보장하는 동시에, 해당 인스턴스에 대한 전역적인 접근 지점을 제공하는 생성 디자인 패턴입니다. 이는 설정 관리자, 커넥션 풀 또는 로깅 서비스와 같이 공유되어야 하는 리소스에 유용합니다.

이 패턴은 생성자를 private으로 설정하여 직접적인 인스턴스화를 방지하는 방식으로 작동합니다. 대신, 정적 메서드가 단일 인스턴스에 대한 접근을 제어합니다:

public class DatabaseConnection {
    private static DatabaseConnection instance;
    
    // 프라이빗 생성자는 직접적인 인스턴스화를 방지합니다
    private DatabaseConnection() {
        System.out.println("Connection created");
    }
    
    // 전역 접근 지점
    public static DatabaseConnection getInstance() {
        if (instance == null) {
            instance = new DatabaseConnection();
        }
        return instance;
    }
    
    public void query(String sql) {
        System.out.println("Executing: " + sql);
    }
}

getInstance()를 호출할 때마다 동일한 객체가 반환됩니다. 인스턴스는 처음 요청될 때만 생성되며, 이를 지연 초기화(lazy initialization)라고 합니다:

DatabaseConnection db1 = DatabaseConnection.getInstance();
DatabaseConnection db2 = DatabaseConnection.getInstance();

System.out.println(db1 == db2);  // true - 동일한 인스턴스

싱글톤(Singleton)의 핵심 구성 요소는 인스턴스를 보유하는 private static 필드, private 생성자, 그리고 인스턴스를 반환하는 public static 메서드입니다. 이 조합은 객체를 몇 번 요청하더라도 항상 동일한 객체를 얻을 수 있도록 보장합니다.

challenge icon

챌린지

쉬움

싱글톤 패턴(Singleton Pattern)을 사용하여 애플리케이션을 위한 설정 관리자(Configuration Manager)를 만들어 봅시다! 설정 관리자는 애플리케이션의 모든 부분에서 설정에 접근할 때, 몇 번을 요청하더라도 동일한 설정을 공유하도록 보장합니다.

코드는 두 개의 파일로 구성됩니다:

  • AppConfig.java: 애플리케이션 설정 정보를 관리하는 싱글톤 클래스를 생성합니다. AppConfig는 다음을 포함해야 합니다:

    단일 인스턴스를 유지하기 위한 private static 필드.

    appName이라는 이름의 private String 필드와 maxUsers라는 이름의 private int 필드.

    appName"MyApplication"으로, maxUsers100으로 초기화한 후, AppConfig initialized를 출력하는 private 생성자.

    인스턴스가 아직 존재하지 않을 때만 생성하고(지연 초기화, lazy initialization) 이를 반환하는 public static getInstance() 메서드.

    앱 이름을 업데이트하는 setAppName(String name) 메서드.

    최대 사용자 수를 업데이트하는 setMaxUsers(int max) 메서드.

    App: [appName], Max Users: [maxUsers] 형식을 출력하는 displaySettings() 메서드.

  • Main.java: 싱글톤이 올바르게 작동하는지 증명하세요! 새로운 앱 이름(String)과 새로운 최대 사용자 수(integer)라는 두 개의 입력을 받게 됩니다.

    먼저, AppConfig의 인스턴스를 가져와 config1이라는 변수에 저장합니다. displaySettings()를 호출하여 기본값을 표시합니다.

    그 다음, config1에서 setAppNamesetMaxUsers를 호출하여 입력받은 값으로 설정을 업데이트합니다.

    또 다른 인스턴스를 가져와 config2에 저장합니다. config2에서 displaySettings()를 호출하여 config1을 통해 변경된 내용이 반영되었는지 확인합니다.

    마지막으로, config1 == config2를 비교하여 두 참조가 동일한 객체를 가리키는지 여부를 Same instance: [true/false] 형식으로 출력합니다.

새로운 앱 이름(String)과 새로운 최대 사용자 수(integer) 순서로 두 개의 입력을 받게 됩니다.

이 챌린지는 싱글톤 패턴의 핵심적인 이점을 보여줍니다. 설정을 몇 번 요청하더라도 항상 동일한 공유 상태를 가진 동일한 인스턴스를 얻게 됩니다!

치트 시트

싱글톤 패턴(Singleton Pattern)은 애플리케이션 전체에서 클래스의 인스턴스가 단 하나만 존재하도록 보장하며, 해당 인스턴스에 대한 전역적인 접근 지점을 제공합니다.

주요 구성 요소:

  • 단일 인스턴스를 보유하는 private static 필드
  • 직접적인 인스턴스화를 방지하는 private 생성자
  • 인스턴스를 반환하는 public static 메서드

기본 구현:

public class DatabaseConnection {
    private static DatabaseConnection instance;
    
    // Private constructor prevents direct instantiation
    private DatabaseConnection() {
        System.out.println("Connection created");
    }
    
    // Global access point
    public static DatabaseConnection getInstance() {
        if (instance == null) {
            instance = new DatabaseConnection();
        }
        return instance;
    }
    
    public void query(String sql) {
        System.out.println("Executing: " + sql);
    }
}

사용법:

DatabaseConnection db1 = DatabaseConnection.getInstance();
DatabaseConnection db2 = DatabaseConnection.getInstance();

System.out.println(db1 == db2);  // true - same instance

인스턴스는 처음 요청될 때만 생성되는데, 이를 지연 초기화(lazy initialization)라고 합니다. getInstance()를 호출할 때마다 동일한 객체가 반환되어 애플리케이션 전체에서 상태를 공유할 수 있습니다.

직접 해보기

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // 입력 읽기
        String newAppName = scanner.nextLine();
        int newMaxUsers = scanner.nextInt();
        
        // TODO: AppConfig의 첫 번째 인스턴스를 가져와 config1에 저장
        
        // TODO: 기본값을 표시하기 위해 config1에서 displaySettings() 호출
        
        // TODO: config1에서 setAppName 및 setMaxUsers를 사용하여 설정 업데이트
        
        // TODO: 또 다른 인스턴스를 가져와 config2에 저장
        
        // TODO: 변경 사항이 공유되는지 증명하기 위해 config2에서 displaySettings() 호출
        
        // TODO: 두 참조가 동일한 객체를 가리키는지 여부 출력:
        // config1 == config2를 사용하여 "Same instance: [true/false]" 출력
    }
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨