[디자인 패턴] 싱글톤 패턴(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가 용이
- 따라서 공통된 객체를 여러개 생성해서 단 하나의 인스턴스로 사용하는 경우에 사용
- 음성 안내의 경우를 예를들면
음성 안내의 출력을 관리하는 클래스를 싱글톤 패턴으로 구현하면 음성 안내가 겹칠 일이 없다!
싱글톤 패턴의 단점
- 확장에는 열려 있어야 하고, 수정에 대해서는 닫혀 있어야 한다는 '개방-폐쇄 원칙' 어길 수 있음
- 개발이 진행됨에 따라 싱글톤 클래스가 복잡해질 수 있음
- 멀티 쓰레드 환경에서 동기화처리의 부재로 여러 개의 인스턴스가 생길 수 있음
마치며
디자인 패턴 중 싱글톤 패턴을 조사하면서 가장 들었던 생각이 '이걸 언제 사용할까?' 였습니다.
이 이유는 알맞은 특수한 경우에 사용하기 때문이라고 생각합니다.
따라서, 디자인 패턴은 적재적소에 사용하여야 유의미한 결과를 얻는다고 생각합니다.
싱글턴 패턴을 시작으로 다른 패턴들도 공부해야겠습니다...😂
Author And Source
이 문제에 관하여([디자인 패턴] 싱글톤 패턴(Singleton Pattern)에 대하여), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@pppp0722/Design-Pattern-싱글톤-패턴Singleton-Pattern이란저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)