백엔드 개발자
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개의 인스턴스생성을 한번만 호출해서 처리하는 방식.
사용자가 다른 인스턴스생성으로 인한 걱정을 덜어줄 수 있는 방식으로 생각된다.
출처
- 사이트, 검색명 (날짜)