[디자인 패턴] 싱글톤 패턴(Singleton Pattern)

Aug 18, 2024
[디자인 패턴] 싱글톤 패턴(Singleton Pattern)
 

1. 싱글톤 패턴

싱글톤 패턴(Singleton Pattern)은 객체지향 프로그래밍에서 특정 클래스의 인스턴스를 오직 하나만 생성하도록 보장하는 디자인 패턴이다. 이렇게 생성된 하나의 인스턴스는 전역적으로 접근 가능하며, 다른 곳에서 새로 인스턴스를 만들지 않도록 한다.
 
💡
main()이 실행되기 전에 JVM 은 static 을 먼저 찾는다. 찾으면서 필드를 실행시킨다.
함수는 호출 시에 열리지만, 변수는 바로 실행되어버린다.
 
싱글톤 패턴을 사용하여 Doorman 객체가 두 개 생성되지 않게 해보자.
 
package ex04; /* Animal 생성(abstract) 타입 일치(다형성) = 쥐(동물), 호랑이(동물) 문지기한테 DIP 만 지켜주면 됨 */ public class App { public static void main(String[] args) { Doorman d1 = new Doorman(); Doorman d2 = new Doorman(); // new 두번 하는거 막기(싱글톤 패턴) } }
notion image
 
 
생성자의 접근제한자를 public -> private 으로 바꾸어 new 로 여러개의 객체가 만들어지는 것을 막는다.
Doorman 클래스의 doorman 인스턴스를 만들 때, 단 한번만 사용하기 위해 static 을 붙여준다.
 
package ex04; // 문지기 public class Doorman { private static Doorman doorman = new Doorman(); // 단 한번만 사용하기 위해 static 으로 private Doorman() {} // 생성자의 접근제한자를 private 으로 // 동물이면 쫓아내 public void 쫓아내(Animal a) { System.out.println(a.getName() + " 쫓아내"); } }
 
외부에서 사용하기 위해 doorman 인스턴스를 리턴해주는 getInstance() 메서드를 만들고, static 을 붙여준다.
 
package ex04; // 문지기 public class Doorman { private static Doorman doorman = new Doorman(); // 단 한번만 사용하기 위해 static 으로 public static Doorman getInstance() { // 외부에서 끌어다 쓰기 위해 static 을 붙여야한다. return doorman; } private Doorman() {} // 생성자의 접근제한자를 private 으로 // 동물이면 쫓아내 public void 쫓아내(Animal a) { System.out.println(a.getName() + " 쫓아내"); } }
 

1-1. deep dive

 
그림으로 이해하면 쉽다.
 
notion image
 
Doorman의 static 이라는 공간이 변수 doorman을 관리한다.
 
notion image
-는 private, +는 public 을 의미한다.
doorman 변수 이름이 안뜬다. private 이라, getInstance를 호출해서 Doorman 의 쫓아내를 찾아낸다.
 
private static Doorman doorman = new Doorman();
 
오른쪽 우변에서 heap 이 만들어지고, 왼쪽 static 메모리에 doorman 이 저장된다.
static 공간에는 doorman 변수와 getInstance 가 뜨고, getInstance()의 호출로 인해
heap 공간에는 실제로는 쫓아내() 가 뜬 것이다.
 
doorman 객체가 main 시작 전에 떠있는거라고 생각하면 된다. 화면에만 안보일뿐.
 

2. 적용

 
잘 적용되었는지 확인해보자.
 
package ex04; // 문지기 public class Doorman { private static Doorman doorman = new Doorman(); public static Doorman getInstance() { return doorman; } private Doorman() {} // 동물이면 쫒아내 public void 쫒아내(Animal a){ System.out.println(a.getName()+" 쫒아내"); } }
package ex04; /* Animal 생성(abstract) 타입 일치(다형성) = 쥐(동물), 호랑이(동물) 문지기한테 DIP 만 지켜주면 됨 */ public class App { public static void main(String[] args) { Doorman d1 = Doorman.getInstance(); Doorman d2 = Doorman.getInstance(); System.out.println(d1.hashCode()); // 주소를 해시화 한 것, 실제 메모리 주소가 아님 System.out.println(d2.hashCode()); // 해시의 난수 // Doorman d2 = new Doorman(); // new 두번 하는거 막기(싱글톤 패턴) } }
 
main 을 실행하면, 아래와 같이 출력된다.
 
notion image
 
d1, d2 의 주소를 해시화 한 것이 동일하게 나오기 때문에 같은 인스턴스라는 의미^^
해시는 아래의 링크 참고
 
실제로 사용 할 때에는 아래와 같이 사용하면 된다.
 
package ex04; public class App { public static void main(String[] args) { Doorman d1 = Doorman.instance; Doorman d2 = Doorman.instance; System.out.println(d1.hashCode()); System.out.println(d2.hashCode()); } }
package ex04; // 문지기 public class Doorman { public static Doorman instance = new Doorman(); // 단 한번만 사용하기 위해 static 으로 private Doorman() {} // 생성자의 접근제한자를 public -> private 으로, new 로 여러개의 객체가 만들어지는 것을 막는다 // 동물이면 쫓아내 public void 쫓아내(Animal a) { System.out.println(a.getName() + " 쫓아내"); } }
 
 
Share article

eunmouse