Singleton (싱글톤) 패턴이란?

먼저 싱글톤 패턴이 정확히 무엇인지 알기 전 이론 상 개념을 조금 알아야 한다
간편하게 위키백과의 내용을 가져와봤다.

소프트웨어 디자인 패턴에서 싱글턴 패턴을 따르는 클래스는, 생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이고 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴한다. 이와 같은 디자인 유형을 싱글턴 패턴이라고 한다.

이 정도면 이론적인 개념은 다 알았다고 생각한다. 이론 끝!

Singleton 기본 코드

이제 코드로 바로 알아보겠다
다음은 싱글톤 패턴만 적용한 기본 코드이다.

  • Singleton.class
public class Singleton {
    private static Singleton singleton;

    private Singleton(){
    }

    public static Singleton getInstance(){
        if(singleton == null){
            singleton = new Singleton();
        }

        return singleton;
    }
}
  • Main.class
public class Main {
    public static void main(String[] args) {
        Singleton singleton1 = Singleton.getInstance();
        Singleton singleton2 = Singleton.getInstance();

        System.out.println(singleton1 == singleton2);
    }
}

위와 같은 코드에서 main() 메서드를 실행시키면 어떤 결과가 나올까?

  • 실행 결과

    true

위와 같이 true가 나온다.
그 이유는 코드를 잘 볼 수 있는 분이라면 다 이해한 걸로 간주하고 간단하게 설명하겠다.

Singleton 클래스의 생성자가 private 으로 선언하므로 다른 클래스에서 객체를 생성하지 못한다.

	private Singleton(){
	
	}

다음으로 private의 static 으로 자기 자신의 객체를 미리 선언해준다.

	private static Singleton singleton;

마지막으로 public의 static으로 선언하고 자기의 객체를 반환해주는 메서드를 생성해준다.
만약 static 으로 선언된 singleton 변수가 null 이라면 new 키워드를 통해 객체 생성 후 반환을 시켜주고,
singleton 변수가 null 이 아니라면(이미 new 키워드를 통해 객체를 만들어놨다면) 바로 반환해준다.

    public static Singleton getInstance(){
        if(singleton == null){
            singleton = new Singleton();
        }

        return singleton;
    }

그 후, Main 클래스에서 getInstance() 메서드를 통해 두 객체를 생성해주고 비교를 해보면 true 가 나온다.

어따 씀?

그럼 이제 과연 어디다 쓸까?
기본 코드와 실행 코드를 보면 이 패턴의 이점은 다른 클래스에서 싱글톤 패턴을 적용한 클래스를 사용할 때 같은 인스턴스를 참조하는 것 밖에 없다. 사실 이게 바로 싱글톤 패턴의 핵심이다.

그럼 실전에서는 어떻게 사용될까?
실전에서는 대부분 구성 관리로 많이 사용한다.

바로 코드를 확인해보자.
아래의 코드들은 모두 예시로 표현했기 때문에 참고만 하기 바란다.

  • Settings.class
import java.util.HashMap;
import java.util.Map;

public class Settings {
    private static Settings instance;
    private Map<String, Integer> settingData;

    private Settings(){
        settingData = new HashMap<>();
        settingData.put("timeout", 3000);
        settingData.put("warningCount", 5);
    }

    public static Settings getInstance() {
        if(instance == null){
            instance = new Settings();
        }
        return instance;
    }

    public Integer getSettingData(String key){
        return settingData.get(key);
    }
}
  • Main.class
public class Main {
    public static void main(String[] args) {
        Settings settings = Settings.getInstance();

        System.out.println(settings.getSettingData("timeout"));
        System.out.println(settings.getSettingData("warningCount"));
    }
}
  • 실행 결과

    3000
    5

기본 코드에서 크게 달라진 건 없기 때문에 설명은 생략하도록 하겠다.
어쨌든 실전에서는 위와 같이 사용을 한다.
구성 관리에서 싱글톤 패턴을 사용하면 사용하는 곳들이 한 인스턴스만 참조하고 있기 때문에 구성을 변경해주면 사용한 모든 곳이 변경된다는 이점이 있다. (ex 다크화면, 폰트 등)

끝으로 싱글톤 패턴은 전역 액세스와 같은 강력한 기능을 제공하지만 반대로 싱글톤 패턴은 범위가 전역이기 때문에 복잡하게 사용하면 유지 보수 및 디버깅에 어려움이 있을 수도 있다.

1개의 댓글

comment-user-thumbnail
2023년 7월 27일

유익한 글이었습니다.

답글 달기

관련 채용 정보