✍️ 학습 목표
- 싱글턴 이해하기
- 싱글턴 vs 정적 클래스
📌 싱글턴 이해하기
싱글턴이란, 인스턴스를 오직 하나만 생성할 수 있는 클래스를 말한다.
🛠️ 싱글턴 만들기
1️⃣ private static final 필드 방식
class Pokemon {
public static final Pokemon INSTANCE = new Pokemon();
private Pokemon() { }
}
- 싱글턴임을 확실하게 알 수 있고 간결하다.
하지만 리플랙션 API를 사용해서 private 생성자에 접근하면 제 2의 인스턴스가 만들어질 수도 있다.
추가적인 인스턴스가 생성되려고 할 때 예외를 던지는 방식으로 이런 공격을 방어할 수 있다.
2️⃣ 정적 팩토리 메서드 방식
class Pokemon {
private static final Pokemon INSTANCE = new Pokemon();
private Pokemon() { }
public static Pokemon getInstance() { return INSTANCE; }
}
- API 변경 없이 싱글턴을 해제할 수 있다.
- 정적 팩토리를 제네릭 싱글턴 팩토리로 만들 수 있다.
- 정적 팩토리의 메서드의 참조를 공급자로 사용할 수 있다.
위 방법들은 싱글턴 클래스를 Serializable로 구현해서 직렬화해도 역직렬화할 때 새 인스턴스가 만들어질 수 있다.
가짜 인스턴스가 생성되는 것을 방지하려면 readResolve 메서드를 추가해 싱글턴임을 보장해야 한다.
3️⃣ 열거 타입 방식
enum Pokemon {
INSTANCE;
}
열거 타입은 본래 private한 생성자를 가지고, 상수만을 받는 클래스라서 싱글턴임을 보장할 수 있다.
복잡한 직렬화 상황이나 리플랙션 공격에도 추가적인 인스턴스가 생성됨을 완벽히 막아준다.
하지만 상속이 필요한 상황에서는 사용할 수 없다.
📌 싱글턴 vs 정적 클래스
언뜻 보면 비슷해 보이는 싱글턴과 정적 클래스의 차이에 대해서 이해해 보자!
🤔 싱글턴
단 하나의 인스턴스만을 생성해서 재사용하는 방식을 의미한다. 다음과 같은 특징들을 가진다.
- 정적 클래스와 다르게 인터페이스를 통해 확장이 가능한다.
- 인스턴스를 생성하는 방법을 다르게 구현하면 생성 시점을 조절할 수 있다.
- 클래스 객체라서 직렬화가 가능하고, 힙 영역에 저장되어 스레드 간에 공유가 가능하다.
🤔 정적 클래스
정적 메서드를 가지는 클래스로 인스턴스를 생성하지 않는다. 다음과 같은 특징들을 가진다.
- 애플리케이션이 메모리 영역에 로드될 때 스택 영역에 바로 초기화된다.
- 인스턴스가 생성되지 않으므로 표준 클래스보단 함수에 더 가깝다.
- 스택 영역에 저장되어 스레드 관리가 어렵다.
둘의 가장 큰 차이는 의존성을 분리할 수 있는 지이다.
싱글턴 클래스는 분리가능한 의존성으로 연결되어있는 반면에 정적 클래스는 하드 코딩된 결정체이다.
어떤 것을 사용하면 더 좋은지는 내 생각엔 의존성에 따라 생각해보는 게 좋을 것 같단 생각이다😋😋
(실은 잘 모르겠다)
😋 지극히 개인적인 블로그지만 훈수와 조언은 제 성장에 도움이 됩니다 😋
'개인 공부 > Java (이펙티브 자바)' 카테고리의 다른 글
[이펙티브 자바] 아이템 6 : 불필요한 객체 생성을 피하라 (0) | 2023.01.15 |
---|---|
[이펙티브 자바] 아이템 5 : 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 (0) | 2023.01.15 |
[이펙티브 자바] 아이템 4 : 인스턴스화를 막으려거든 private 생성자를 사용하라 (0) | 2023.01.02 |
[이펙티브 자바] 아이템 2 : 생성자에 매개변수가 많다면 빌더를 고려하라 (0) | 2022.12.21 |
[이펙티브 자바] 아이템 1 : 생성자 대신 정적 팩토리 메서드를 고려하라 (0) | 2022.12.07 |
댓글