![[디자인 패턴] 4. Singleton 패턴](https://image.inblog.dev?url=https%3A%2F%2Finblog.ai%2Fapi%2Fog%3Ftitle%3D%255B%25EB%2594%2594%25EC%259E%2590%25EC%259D%25B8%2520%25ED%258C%25A8%25ED%2584%25B4%255D%25204.%2520Singleton%2520%25ED%258C%25A8%25ED%2584%25B4%26logoUrl%3Dhttps%253A%252F%252Finblog.ai%252Finblog_logo.png%26blogTitle%3Djay0628&w=2048&q=75)
Contents
싱글톤 패턴싱글톤 패턴
싱글톤 패턴이란 프로그램 전체에서 단 하나의 인스턴스만 존재해야할 때 사용되는 디자인 패턴이다.
왜 객체를 하나만 만들어야 할까?
먼저 상태를 공유해야하는 경우가 있다. 어떤 클래스가 공용 자원이나 상태를 관리할 때 여러 객체가 만들어지면 각각의 상태가 따로 존재하게 되어 중복 등의 문제가 생길 수 있다.
두번째로 각체 생성 비용이 큰 경우이다. 어떤 클래스는 객체를 생성할 때 비용이 많이 들게 되고 (예 : DB 연결, 설정 파일 로딩 등) 그때마다 new를 통해 객체를 만들면 성능이 낭비되므로 한 번만 만들어두고 공유해서 쓰는 것이 효율적이다.
마지막으로 전역적으로 하나만 존재해야 하는 개념이 경우이다. 문지기와 동물들 예제를 기준으로 생각해보면 문지기는 하나만 있어도 충분하고 그 외에도 프로그램 구조상 전역적으로 하나만 존재해야하는 역할이 존재한다.
예제 - 문지기와 동물들
현재 Doorman 객체가 두 개 생성되어있는 상황이고 문지기를 하나만 띄우는 것이 목적이다.

우선 생성자를 private으로 만들어서 밖에서는 만들지 못하도록 한다. 그리고
public static
Doorman
instance
=
new
Doorman();
코드를 통해 객체를 하나만 생성한다.public static
Doorman
instance
=
new
Doorman();
이 코드를 조금 더 자세하게 살펴보자.먼저 프로그램을 실행하게 되면 main함수가 실행되기 전 static부터 찾으므로 위의 코드가 시작된다. 그리고 코드는 우변부터 실행되므로 heap 영역에 Doorman 타입으로 만들어 진다. 원래는 main 함수 시작 전에 new를 통해 heap 영역에 객체가 생성될 수 없지만 static에 의해 heap이 main 함수 시작 전에 메모리에 뜰 수 있다. 그러나 생성자를 private으로 만들었고 static은 main 함수 시작 전에 딱 한번만 뜨니까 Doorman은 heap에 한번만 뜨게 된다.
좌변을 보면 static 영역에 Doorman 타입의 공간이 생기고 그 공간에 instance 변수가 저장된다. instance 주소는 heap 영역의 Doorman 객체를 가리키므로 해당 주소를 ????

이렇게 코드를 작성하게 되면 main함수가 실행되기 전 static부터 찾게 되니까 위의 코드가 시작된다. 코드는 우변부터 실행되므로 heap영역에 Doorman 타입으로 만들어지고

package ex04;
public class App {
public static void main(String[] args) {
Mouse m1 = new Mouse();
Cat c1 = new Cat();
Doorman d1 = Doorman.instance;
d1.쫓아내(m1);
d1.쫓아내(c1);
}
}
package ex04;
public class Doorman {
public static Doorman instance = new Doorman(); // 원래는 private 하고 getter를 만들어야 하지만 여기서는 중요X
// // 이건 책임이고 싱글톤 아님 -> 복잡한 객체일때
// public static Doorman createInstance(){
// return new Doorman();
// }
// // 책임X 상태확인
// public Doorman getInstance() {
// return instance;
// }
private Doorman() {
}
// 객체의 책임 = 메서드
public void 쫓아내(Animal a) {
System.out.println(a.getName() + " 나가!");
}
}
Share article