[디자인 패턴] 싱글톤 패턴(Singleton Pattern)에 대하여

싱글톤 패턴(Singleton Pattern)

싱글톤 패턴이란?

  • 어떤 클래스가 최초 한번 메모리를 할당하고 해당 메모리에 여러 레퍼런스를 생성하여 사용하는 디자인 패턴

  • static을 사용하여 인스턴스 생성

  • 싱글톤 패턴을 사용하지 않는 경우

    // Dog.java
    public class Dog {
        private String name;
        
        public Dog(String name) {
            this.name = name;
        }
        
        public void bark() {
            System.out.println(name + ": " + "멍!");
        }
    }
    // Main.java
    public class Main {
        public static void main(String[] args) {
            Dog dog1 = new Dog("dog1");
            Dog dog2 = new Dog("dog2");
            
            dog1.bark();
            dog2.bark();
            
            if (dog1.equals(dog2)) {
                System.out.println("dog1 & dog2 => 같습니다.");
            } else {
                System.out.println("dog1 & dog2 => 다릅니다.");
            }
        }
    }

    실행 결과


    dog1: 멍!
    dog2: 멍!
    dog1 & dog2 => 다릅니다.

    • dog1과 dog2는 다른 이름을 가질 수 있으며 같은 인스턴스가 아님
    • 즉, 메모리에 Dog이 2번 할당

  • 싱글톤 패턴을 사용하는 경우

    // SingleDog.java
    public class SingleDog {
        private static final SingleDog instance = new SingleDog("singleDog");
        private static String name;
        
        private SingleDog(String name) {
            this.name = name;
        }
        
        public static SingleDog getInstance() {
            return instance;
        }
        
        public void changeName(String name) {
            this.name = name;
        }
        
        public void bark() {
            System.out.println(name + ": " + "멍!");
        }
    }
    // Main.java
    public class Main {
        public static void main(String[] args) {
            SingleDog singleDog1 = SingleDog.getInstance();
            SingleDog singleDog2 = SingleDog.getInstance();
            
            singleDog1.changeName("singleDog1");
            singleDog2.changeName("singleDog2");
            
            singleDog1.bark();
            singleDog2.bark();
            if (singleDog1.equals(singleDog2)) {
                System.out.println("singleDog1 & singleDog2 => 같습니다.");
            } else {
                System.out.println("singleDog1 & singleDog2 => 다릅니다.");
            }
        }
    }

    실행 결과


    singleDog2: 멍!
    singleDog2: 멍!
    singleDog1 & singleDog2 => 같습니다.

    • singleDog1과 singleDog2는 다른 이름을 가질 수 없으며 같은 인스턴스
    • 즉, 메모리에 singleDog이 1번 할당 & 해당 메모리에 2개 인스턴스 생성


Java에서 싱글톤 패턴 구현

  • Eager Initialization
    • 가장 간단한 형태의 구현 방법
    • 어플리케이션에서 해당 인스턴스를 사용하지 않더라도 클래스 로딩 단계에서 인스턴스 생성
public class Singleton {
    private static final Singleton instance = new Singleton();
    
    private Singleton(){}
 
    public static Singleton getInstance(){
        return instance;
    }
}

  • Lazy Initialization
    • 나중에 인스턴스를 초기화하는 방법 => 무의미한 인스턴스 생성 방지
    • 멀티 쓰레드 환경에서 동시에 getInstance()를 호출하면 예상치 못한 결과 생김
    • 여러 인스턴스가 생성된다면 싱글톤 패턴이 아니기 때문에 싱글 쓰레드 환경에서만 사용
public class Singleton {
    private static Singleton instance;
    
    private Singleton(){}
    
    public static Singleton getInstance(){
        if(instance == null){
            instance = new Singleton();
        }
        return instance;
    }
}

  • Bill Pugh Singleton Implementaion
    • Bill Pugh가 고안한 방식으로, inner static class를 사용하는 방식
    • helper 클래스는 getInstance()가 호출 되었을 때 비로소 인스턴스 생성 => 무의미한 생성 방지
    • 클래스가 로드될때 인스턴스가 생성되므로 멀티 스레드 환경에서도 안전
public class Singleton {
    private Singleton(){}
    
    private static class SingletonHelper{
        private static final Singleton INSTANCE = new Singleton();
    }
    
    public static Singleton getInstance(){
        return SingletonHelper.INSTANCE;
    }
}


어떤 경우에 싱글톤 패턴을 사용할까?

  • 고정된 메모리 영역에서 단 하나의 인스턴스를 가지므로 메모리 낭비 방지
  • 싱글톤으로 만들어진 클래스의 인스턴스는 전역 인스턴스이기 때문에 전역 setter, getter가 용이
  • 따라서 공통된 객체를 여러개 생성해서 단 하나의 인스턴스로 사용하는 경우에 사용

  • 음성 안내의 경우를 예를들면

    음성 안내의 출력을 관리하는 클래스를 싱글톤 패턴으로 구현하면 음성 안내가 겹칠 일이 없다!


싱글톤 패턴의 단점

  • 확장에는 열려 있어야 하고, 수정에 대해서는 닫혀 있어야 한다는 '개방-폐쇄 원칙' 어길 수 있음
  • 개발이 진행됨에 따라 싱글톤 클래스가 복잡해질 수 있음
  • 멀티 쓰레드 환경에서 동기화처리의 부재로 여러 개의 인스턴스가 생길 수 있음


마치며

디자인 패턴 중 싱글톤 패턴을 조사하면서 가장 들었던 생각이 '이걸 언제 사용할까?' 였습니다.
이 이유는 알맞은 특수한 경우에 사용하기 때문이라고 생각합니다.

따라서, 디자인 패턴은 적재적소에 사용하여야 유의미한 결과를 얻는다고 생각합니다.
싱글턴 패턴을 시작으로 다른 패턴들도 공부해야겠습니다...😂

좋은 웹페이지 즐겨찾기