Java

싱글톤

공부처음하는사람 2024. 6. 23. 23:14

 

애플리케이션 전체에서 단 한개의 객체만 생성해서 사용하고 싶다면 싱글톤 패턴을 적용할 수 있다.

싱글톤 패턴의 핵심은 생성자를 private로 선언해 외부에서 new 연산자로 생성자를 호출할 수 없게 하는 것이다.

생성자를 호출할 수 없으니 외부에서 객체를 생성하는 것이 불가능해진다. 대신 싱글톤 패턴이 제공하는 정적 메서드를 통해

간접적으로 객체를 생성할 수 있다.

package ch06.sec15;

public class Singleton {
    // private 접근 권한을 갖는 정적 필드 선언과 초기화
    private static Singleton singleton = new Singleton(); // **1번**

    // private 접근 권한을 갖는 생성자 선언
    private Singleton() {
    }

    // public 접근 권한을 갖는 정적 메소드 선언
    public static Singleton getInstance() {  // **2번**
        return singleton;
    }
}

 

**1번** 에서는 자신의 타입으로 정적 필드를 선언하고 미리 객체를 생성해서 초기화 시킨다. 그리고 private 접근 제한자를 붙여

외부에서 정적 필드값을 변경하지 못하도록 막는다.

 

**2번** 에서는 정적 필드값을 리턴하는 getInstance() 메서드를 public으로 선언했다.

외부에서 객체를 얻는 유일한 방법은 getInstance 메서드를 호출하는 것이다. 메서드가 리턴하는 객체는 정적 필드가 참조하는

싱글톤 객체이다.

 

package ch06.sec15;

public class SingletonEx {
    public static void main(String[] args) {

//        Singleton obj1 = new Singleton();
//        Singleton obj2 = new Singleton();  // 컴파일 에러

        // 정적 메소드를 호출해서 싱글톤 객체를 얻음

        Singleton obj1 = Singleton.getInstance();
        Singleton obj2 = Singleton.getInstance();

        // 동일한 객체를 참조하는지 확인
        if (obj1 == obj2) {
            System.out.println("같은 싱글톤 객체입니다.");
        } else {
            System.out.println("다른 싱글톤 객체입니다.");
        }
    }
}

 

new 연산자로 객체를 호출할 수 없다. (컴파일 에러 발생)

따라서 아래 코드에서는 obj1과 obj2는 같은 객체를 참조하게 되는것이다.

인스턴스는 하나만 생성된다.

 

싱글톤 패턴의 구현방법 중 eagger, lazy, double-checked locking 등 다양한 방법이 있는데

일단 오늘은 구현방법은 넘어가고..

 

싱글턴 패턴의 장점

1. 애플리케이션 전역에서 동일한 인스턴스를 사용할 수 있음

2. 단일 인스턴스를 사용하기 때문에 메모리를 절약할 수 있음

3. 인스턴스 생성과 초기화 로직을 한곳에서 제어할 수 있음

 

단점

1. 전역에서 사용되기 때문에 유닛테스트 어려움

2. 코드 내에서 싱글톤에 의존하는 부분이 명확하지 않아 리팩터링 어려움 있을 수 있음

3. 똑바로 쓰지 않으면 멀티쓰레드 환경에서 문제 생길 가능성 있음