본문 바로가기
Programming/디자인 패턴

싱글턴 패턴 Singleton Pattern

by Bam_t 2021. 9. 13.
728x90

이번에 소개드릴 패턴은 싱글턴 패턴입니다.


1. 싱글턴 패턴

싱글턴 패턴은 이름에서 single;하나의 라는 의미가 들어가 있듯이 하나의 인스턴스 생성을 위한 패턴입니다. 즉, 단 한번의 객체 생성을 보장하는 패턴입니다.

처음들을때는 객체 생성을 단 한번만 한다니까 의미없고 이상해보입니다. 하지만 생각해보면 의외로 단 하나의 객체 생성만을 보장해야 하는 경우가 꽤 있습니다. 대표적으로 설정을 저장하는 객체가 있습니다. 설정은 사용자가 단 하나의 설정을 이용하죠. 만약에 설정이 여러개라면 설정끼리 충돌하는 상황이 발생하기 때문에 이런 설정 객체 같은 경우 단 하나의 인스턴스 생성을 보장해야합니다.

 

 

2. 싱글턴 패턴 구현

싱글턴 패턴은 여태까지의 패턴과는 다르게 구현 전에 잠시 생각해 봐야할 것들이 있습니다.

먼저, 객체 생성 부분을 짚자면, 단 하나의 객체 생성을 보장하는 패턴이기에 외부에서 접근하면 당연히 안됩니다. 또한 상속도 허용해서는 안됩니다.

  • 외부 접근 차단 -> private 키워드
  • 상속 비허용 -> final

 

싱글턴 객체로 생성한 유일한 객체는 class에 담아두는 것이 제일 좋습니다. 그렇다면 클래스내에서 값이 변하지 않고, 인스턴스 생성 없이도 호출이 가능하게 해주는 static키워드를 이용하는 것도 고려해볼 사항입니다. 그러면 이 두가지 사항을 유념하시고 구현으로 넘어가보겠습니다.

 

class Singleton {
    private Singleton() {}//private로 설정된 생성자
    
    public static Singleton getInstance() {
        return new Singleton();
    }
}

이것이 싱글턴 패턴의 기본 구조입니다. 생성자의 접근지정자로 private를 넣음으로써 외부에서 따로 인스턴스 생성이 불가해졌습니다. 그리고 getInstance() 메소드가 객체의 생성을 담당하는데 제어자로 public static을 넣음으로써, 어디에서 든지 동일한 값을 담고 있게 해주었습니다.

하지만 이것이 완성은 아닙니다. 바로 getInstance() 메소드를 호출할 때 마다 싱글턴 객체가 생기게 되는데, 이러면 싱글턴 객체의 기본 개념인 유일한 객체개념이 무너지게 됩니다. 그래서 우리는 이 뼈대에 살을 붙여서 완성시켜야합니다.

 

class Singleton {
    private static Singleton onlyOneInstance;	//인스턴스를 담을 변수
    
    private Singleton() {}

    public static Singleton getInstance() {
        if (onlyOneInstance == null) {	//담는 변수가 비어있을 경우에만!!!!!!
            onlyOneInstance = new Singleton();	//싱글턴 객체 생성!!!!!
        }
        return onlyOneInstance;
    }
}

이것이 완성된 싱글턴 패턴입니다. 우선, 싱글턴 인스턴스를 담을 멤버 변수를 하나 만들어줍니다. 이때 private 외에도 값이 변하면 안되므로 static을 붙여주어야 합니다. 그리고 인스턴스를 생성하는 getInstance() 메소드를 보시면 인스턴스를 담는 변수가 비어있는 경우에만 객체를 생성합니다. 이렇게 하면 단 한 번만 객체가 생성되겠죠?

 

싱글턴이 짧지만 조금은 난해할 수 있는 관계로 이번에는 특별히 메인 메소드도 간단하게 만들어서 보여드리려고합니다.

Singleton s = new Singleton(); <- 불가능!!!
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();

우선 객체 생성 부분입니다. 생성자가 private였으므로 위와같이 new를 통해서 객체를 생성하는 것은 불가능 하고 아래처럼 멤버 함수를 통해서만이 생성이 가능합니다.

그런데 보면 s1과 s2 두개가 만들어졌죠? 이 두가지 객체는 같은 것일까요, 다른것일까요?

결과는 메인 메소드 전체를 보고서 확인시켜드리겠습니다.

public class SingletonMain {
    public static void main(String[] args) {
        //Singleton s = new Singleton(); <- 불가능!!!
        Singleton s1 = Singleton.getInstance();
        Singleton s2 = Singleton.getInstance();

        if(s1 == s2){
            System.out.println("s1과 s2는 같은 객체입니다.");
        }
        else {
            System.out.println("s1과 s2는 다른 객체입니다.");
        }
    }
}

if문을 통해 s1과 s2과 동일한 객체면 같은 객체라고 메세지가 출력될 것이고, 다른 객체라면 다른 객체라고 메세지가 출력될 것 입니다.

결과는 같은 객체였습니다. 이처럼 이름이 다르더라도 내용은 같은객체, 즉 단 하나의 객체를 이용하고 있습니다.


싱글턴이 원리는 간단한데 구현이 은근히 까다로운 패턴이었습니다. 그래서 예시를 들어 설명하기 보단 직접적인 구조를 보여드리고 싶어서 이번만큼은 예시를 들지 않고 구현해봤습니다.

https://github.com/Bam-j/DesignPattern/tree/master/src/Singleton

 

728x90

댓글