백엔드 개발자 2024. 3. 22. 23:59

 

 

 

 

사용되는 시점


  • 프로그램상 클래스의 인스턴스가 하나만 있어야 할 경우
  • 프로그램상 여러곳에서 공유되는 설정(ex 로그인)
  • 멀티쓰레딩 환경에서 공유되는 리소스
  • 전역으로 공유되는 인스턴스가 필요한 경우

 

 

 

 

1. 싱글톤 사용없이 진행


  • 탭의 볼륨기능을 인스턴스화.
  • 탭마다 각각 다른 인스턴스를 생성.
  • 특정 탭에서 볼륨을 올려도 다른탭에는 적용이 안된다. 각각 가지고 있는 세팅이 다름.

 

원하는 건 탭에 공통으로 볼륨을 올리는 것인데, 각자 인스턴스가 달라서 공통으로 관리하지 못하고 탭마다 일일이 올려주어야 하는 문제 발생.

 

 

 

 

2. 싱글턴없이 진행2


 

public static void main(String[] args) {
    //  공유시킬 인스턴스
    Setting setting = new Setting();

    //  💡 방법 1 : 생성자로 주입
    Tab tab1 = new Tab(setting);
    Tab tab2 = new Tab(setting);

    //  💡 방법 2 : setter로 주입
    Tab tab3 = new Tab();
    tab3.setSetting(setting);

    System.out.println(tab1.getSetting().getVolume());
    System.out.println(tab2.getSetting().getVolume());
    System.out.println(tab3.getSetting().getVolume());

    System.out.println("\n- - - - -\n");

    tab1.getSetting().incVolume();
    tab1.getSetting().incVolume();

    System.out.println(tab1.getSetting().getVolume());
    System.out.println(tab2.getSetting().getVolume());
    System.out.println(tab3.getSetting().getVolume());

    //  🤔 인스턴스를 공유할 수 있게 되었지만 번거로움이 남음
    //  - 해당 인스턴스를 외부에서 주입해주어야 함
    //    - 협업 등의 경우 잘못 사용될 여지가 있음
    //  - 더 편리하고 안전한 방법은 없을까?
}

  • 1개의 세팅 인스턴스를 미리 만들어 놓는다.
  • tab 인스턴스를 3개 각각 생성하고, 생성자나 setter로 주입시킨다.
  • 동일한 인스턴스를 가리키게 된다.

 

  • 인스턴스가 공통으로 된 것은 나아진 부분이나, 이 공통 인스턴스를 외부에서 주입해주어야 하고, 협업시 잘못 사용될 여지가 있는 이슈가 있음.

 

안전하지 않은 방식

-> 아예 이런 시도를 못하게 인스턴스 자체가 사용자가 어떻게 사용하든 1개만 들어가도록 하는 것이 싱글턴.

 

 

 

 

 

3. 싱글턴의 사용


  • 인스턴스를 정적 필드로 넣어준다. 메모리에 1개만 존재하게 만들기 위해서(힙영역에 들어가서 1개만 존재.)
  • 생성자를 private로 만들어줌. 외부에서 생성자 접근을 못하게 하도록.
  • 공유된 인스턴스를 받아가는 public 클래스 메서드인 getInstance()를 통해 인스턴스를 가져온다.
  • 인스턴스가 없으면 생성, 아니면 그대로 있는 인스턴스를 반환해준다.

 

 

 

인스턴스 세팅 과정

  • getInstance로 new Setting() 인스턴스 생성 부분 프로그램에서 1번만 호출된다.
  • Tab 클래스에서 getInstance로 생성된 유일한 인스턴스를 받아온다.

 

 

 

 

Main 함수

public class Main {
    public static void main(String[] args) {
        Tab tab1 = new Tab();
        Tab tab2 = new Tab();
        Tab tab3 = new Tab();

        System.out.println(tab1.getSetting().getVolume());
        System.out.println(tab2.getSetting().getVolume());
        System.out.println(tab3.getSetting().getVolume());

        System.out.println("\n- - - - -\n");

        tab1.getSetting().incVolume();
        tab1.getSetting().incVolume();

        System.out.println(tab1.getSetting().getVolume());
        System.out.println(tab2.getSetting().getVolume());
        System.out.println(tab3.getSetting().getVolume());

        //  🎉 외부에서 각 사용처들을 신경쓸 필요 없음
    }
}
  • 아무리 사용해도 인스턴스는 1개만 생성되었으니 1개의 세팅을 공통으로 사용한다.
  • Tab이라는 클래스를 다룰 때 어떤 인스턴스가 들어가는지 걱정할 필요가 없어진다. (어차피 모두 공통으로 들어가게 될테니까)

 

싱글턴은 1개의 인스턴스를 공통으로 사용해야 하는 경우, 1개의 인스턴스생성을 한번만 호출해서 처리하는 방식.

사용자가 다른 인스턴스생성으로 인한 걱정을 덜어줄 수 있는 방식으로 생각된다.

 

 

 

 

 

 

 

 

출처 

  • 사이트, 검색명 (날짜)