Menu
Coddy logo textTech

싱글톤 패턴

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

싱글턴 패턴은 애플리케이션 전체에서 하나의 instance만 갖도록 보장하면서 해당 instance에 대한 전역 액세스 지점을 제공하는 생성 디자인 패턴입니다. 구성 관리자, 연결 풀 또는 로깅 서비스처럼 공유해야 하는 리소스에 유용합니다.

이 패턴은 constructor를 private으로 만들어 direct instantiation을 방지하는 방식으로 작동합니다. 대신 static 메서드가 단일 instance에 대한 access를 제어합니다:

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()에 대한 모든 호출은 동일한 객체를 반환합니다. instance는 처음 요청될 때만 생성됩니다. 이를 lazy initialization이라고 합니다:

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

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

Singleton의 핵심 구성 요소는 다음과 같습니다. 인스턴스를 보유하는 private static 필드, private 생성자, 그리고 인스턴스를 반환하는 public static 메서드입니다. 이 조합은 객체를 몇 번 요청하든 항상 동일한 객체를 받도록 보장합니다.

challenge icon

챌린지

쉬움

싱글턴 패턴을 사용하여 애플리케이션을 위한 구성 관리자를 만들어 봅시다! 구성 관리자는 애플리케이션의 모든 부분이 몇 번이나 액세스를 요청하더라도 동일한 설정을 공유하도록 보장합니다.

코드를 두 파일로 구성합니다:

  • AppConfig.java: 애플리케이션 구성 설정을 관리하는 싱글턴 클래스를 만듭니다. AppConfig에는 다음이 있어야 합니다:

    단일 인스턴스를 보유할 private static field.

    appName이라는 private String field와 maxUsers라는 private int field.

    appName"MyApplication"으로, maxUsers100으로 초기화한 다음 AppConfig initialized를 출력하는 private constructor.

    아직 인스턴스가 존재하지 않을 때만 인스턴스를 생성하는 lazy initialization을 수행한 후 인스턴스를 반환하는 public static getInstance() method.

    앱 이름을 업데이트하는 setAppName(String name) method.

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

    App: [appName], Max Users: [maxUsers]를 출력하는 displaySettings() method.

  • Main.java: 싱글턴이 올바르게 작동한다는 것을 보여 줍니다! 두 개의 입력을 받습니다. 새로운 앱 이름(String)과 새로운 최대 사용자 수(integer)입니다.

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

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

    또 다른 인스턴스를 가져와 config2에 저장합니다. config1을 통해 변경된 내용이 반영된다는 것을 증명하기 위해 config2에서 displaySettings()를 호출합니다.

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

입력은 다음 순서로 두 개가 주어집니다. 새로운 앱 이름(String), 새로운 최대 사용자 수(integer).

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

직접 해보기

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: 두 참조가 동일한 객체를 가리키는지 여부 출력:
        // "Same instance: [true/false]" using config1 == config2
    }
}
quiz icon실력 점검

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

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

직접 연습해 보세요: 온라인 Java 컴파일러