Singleton Pattern
Singleton Pattern μ 리
μ±κΈν€ ν¨ν΄μ΄λ?
μ±κΈν΄μ ν΄λμ€μ μΈμ€ν΄μ€κ° νλλ§ μλλ‘ νλ©΄μ μ΄ μΈμ€ν΄μ€μ λν μ μ μ κ·Ό(μ‘μΈμ€) μ§μ μ μ 곡νλ μμ± λμμΈΒ ν¨ν΄μ΄λ€.
μ¦, λ°μ΄ν° λ² μ΄μ€μ κ°μ κ²½μ° νλμ μΈμ€ν΄μ€λ§μ κ°μ ΈμΌ νλ€. μ΄λ΄ λ μ±κΈν€ ν¨ν΄μ μ¬μ©νλ€.(μΈμ€ν΄μ€κ° 1κ°λ§ μμμ 보μ¦)
[μ€κ³ ν¨ν΄ μμ μμ]
1
2
- λμμΈ ν¨ν΄μ΄ μλ μ½λ© ν¨ν΄μΌλ‘ 보λ μ¬λλ μμ(κ²½κ³μ μν¨)
- μ¬λ¬ κ°μ§ μ΄μ λ‘ μΈμ€ν΄μ€λ₯Ό νλλ§ μμ±νκ³ , ν΄λμ€λ₯Ό ν΅ν΄ μ°Έμ‘°λ§ νκ²ν¨
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
// μμ±μλ μΈλΆμμ νΈμΆλͺ»νκ² private μΌλ‘ μ§μ ν΄μΌ νλ€.
}
public static Singleton getInstance() {
return instance;
}
public void say() {
System.out.println("hi, there");
}
}
λ³νμ±
*λ³νμ± μ‘°μ¬
μ¬κΈ° μλμ λ°©λ²μ κ°λ¨ν getInstance λΏλ§ μλλΌ λ³νμ± νλ‘κ·Έλλ°μ λν΄ κ³ λ €ν΄λ³Όλ§ν λ¬Έμ λ₯Ό μ μνλ€.
- Lazy Initialization
μλμ κ°μ΄ μ΄λ―Έ ν΄λμ€ λ΄μ μ μλ³μλ‘ μμ± β μμ°μ΄λ κ²½μ° μμ λλΉ
1
2
3
4
5
6
7
8
9
10
11
12
public class Singleton {
private static Singleton uniqueInstance = new Singleton();
// other useful instance variables
private Singleton() {
}
public static Singleton getInstance() {
return uniqueInstance;
// other useful methods }
}
}
- Eager Initialization
νΉμ getInstance ν¨μμ λ³νμ± μ½λ μΆκ° β lockμ΄λ μ±λ₯μ ν
1
2
3
4
5
6
7
8
9
10
11
12
public class Singleton {
private static Singleton uniqueInstance = new Singleton();
// other useful instance variables
private Singleton() {
}
public static synchronized Singleton getInstance() {
return uniqueInstance;
// other useful methods }
}
}
- DCL(double checked locking) (java 1.5 μ΄μμμ 보μ₯) β μ±λ₯ μ°μνλ + ꡬνμ΄ μ΄λ ΅λ€.
1
2
3
4
5
6
7
8
9
10
public static Singleton getInstance() {
if (uniqueInstance == null) {
synchronized (Singleton.class) {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
[Java λ³νμ±, v1.5 ~ ]
- Synchronize: ν΄λΉ λΈλ½μ λν μ κ·Όμ체μμ lockμ ν΅ν΄ λ³νμ± κ΄λ¦¬
- Volatile: ν΄λΉ λ³μμ λμ€
κ³ λ €μ¬ν
- classλ₯Ό μ λΆ staticνκ², ν΄λμ€λΌλ¦¬ 곡μ κ°λ₯νκ² λ§λ€λ©΄ μ±κΈν€μ΄λ λκ°μ κΈ°λ₯μ μνν μ μλ€.
νμ§λ§, μ μ μ΄κΈ°ν λ¨κ³μμ μ¬λ¬ μλ¬κ° λ°μν μ μμΌλ©° λ°μν μλ¬λ μ°ΎκΈ° νλ€λ€.
- ν΄λμ€ λ‘λ
[ν΄λμ€λ‘λλ?]
μλ° ν΄λμ€λ€μ μ»΄νμΌλ λ‘λλμ§ μκ³ , λμ μΌλ‘ νμν λ λ‘λλλ€. ν΄λμ€ λ‘λλ JREμ μΌλΆλ‘μ¨Β λ°νμμ ν΄λμ€λ₯Ό λμ μΌλ‘ JVMμ λ‘λ νλ μν μ μννλ λͺ¨λμ΄λ€. μλ°μ ν΄λμ€λ€μ μλ° νλ‘μΈμ€κ° μλ‘ μ΄κΈ°νλλ©΄ ν΄λμ€λ‘λκ° μ°¨λ‘μ°¨λ‘ λ‘λ©λλ©° μλνλ€.
[λ°μν μ μλ λ¬Έμ ]
ν΄λμ€ λ‘λκ° μ¬λ¬ κ°λΌλ©΄, κ°κΈ° λ€λ₯Έ μ±κΈν€ μΈμ€ν΄μ€λ₯Ό 1κ°μ© μμ ν μ μλ€. μ΄λ λ¬Έμ κ° λ°μνλ―λ‘, ν΄λμ€ λ‘λλ₯Ό μ§μ νκ±°λ μ΄λ₯Ό λ°©μ§ν΄μΌ νλ€.
- μ§λ ¬νμ 리νλ μ
https://inpa.tistory.com/entry/JAVA-β-μ±κΈν€-κ°μ²΄-κΉ¨λ¨λ¦¬λ-λ°©λ²-μμ§λ ¬ν-리νλ μ #μμ§λ ¬νλ‘_κΉ¨μ§λ_μ±κΈν€μμ μμΈνκ² νμΈν μ μλ€.
- loose coupling μμΉ
μ±κΈν€ λ°©λ²μ μ¬μ©νλ©΄, μ±κΈν€ ν΄λμ€κ° λ³κ²½λλ©΄ κ΄λ ¨λ λͺ¨λ ν΄λμ€λ₯Ό λ³κ²½ν΄μΌ νλ€. μ¦, λλΆλΆμ ν΄λμ€κ° μ±κΈν€ ν΄λμ€μ λ΄λΆλ₯Ό μμμΌνλ©° μ΄λ λμ¨ν κ²°ν© μμΉμ μλ°°λλ€.
- μ μλ³μμμ μ°¨μ΄
λκΈ°νλ₯Ό κ³ λ €νμ¬ μμ±νλ©΄, λ³νμ±λΆλΆμ 3λ² νΉμ 2λ² κ²½μ°λΌλ©΄ μ μλ³μμ λ€λ₯΄κ² νλ²μ΄λΌλ μ¬μ©ν΄μΌ μμ±νλ€. λν, ν΄λμ€μ΄κΈ°μ μ κ·Όμ μ΄μ λ± μ¬λ¬ μ₯μ μ΄ μλ€.
κ²°κ³Όμ μΌλ‘?
κ·Έλμ λμ¨ Enum
μλμ κ°μ΄ enumμΌλ‘ ν΄λμ€λ₯Ό μ§μ νλ€. enumμ μλ°μμλ μμκ° μλ ν΄λμ€μ²λΌ μ¬μ©ν μ μλ€. λν, enumμ μμ μ νλ²λ§ μ΄κΈ°ννκΈ°μ μ±κΈν€ μμΉμ μ§ν€λ©°, atomicνκ² μ²λ¦¬λκΈ°μ λ©ν° μ°λ λμμλ μμ νλ€.
μλλ ν€λνΌμ€νΈ κ΄λ ¨ μ½λ μμμ΄λ€.
1
2
3
4
5
6
7
8
9
10
public enum Singleton {
UNIQUE_INSTANCE;
// other useful fields here
// other useful methods here
public String getDescription() {
return "I'm a thread safe Singleton!";
}
}
μλμ κ°μ΄ μ¬μ©νλ©΄ λλ€.
1
2
3
4
5
6
public class SingletonClient {
public static void main(String[] args) {
Singleton singleton = Singleton.UNIQUE_INSTANCE;
System.out.println(singleton.getDescription());
}
}
μ±κΈν€ ν¨ν΄μ λ¨μ
- μ±κΈν€ ν¨ν΄μ ꡬννλ μ½λ μμ²΄κ° λ§μ΄ λ€μ΄κ°λ€.
- μμ‘΄κ΄κ³μ ν΄λΌμ΄μΈνΈκ° ꡬ체 ν΄λμ€μ μμ‘΄νλ€. DIPλ₯Ό μλ°νλ€.
- ν΄λΌμ΄μΈνΈκ° ꡬ체 ν΄λμ€μ μμ‘΄ν΄μ OCP μμΉμ μλ°ν κ°λ₯μ±μ΄ λλ€.
- ν μ€νΈνκΈ° μ΄λ ΅λ€.
- λ΄λΆ μμ±μ λ³κ²½νκ±°λ μ΄κΈ°ν νκΈ° μ΄λ ΅λ€.
- private μμ±μλ‘ μμ ν΄λμ€λ₯Ό λ§λ€κΈ° μ΄λ ΅λ€.
- κ²°λ‘ μ μΌλ‘ μ μ°μ±μ΄ λ¨μ΄μ§λ€.
- μν°ν¨ν΄μΌλ‘ λΆλ¦¬κΈ°λ νλ€.