๋ชฉ์ฐจ
์ด๋ค ์ํฉ์์ ์ฐ์ผ๊น?
์์คํ ๋ฐํ์, ํ๊ฒฝ์ ํ ์ ๋ณด ๋ฑ์ ๊ฐ์ฒด๊ฐ ์ฌ๋ฌ๊ฐ ์์ฑ๋๋ฉด ์ด๋ป๊ฒ ๋ ๊น??
์ฌ๊ธฐ์ ๊ธฐ์ ๊ฐ๊ธฐ ๋ค๋ฅธ ์ ํ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์์ ์ ์๊ฒ๋๊ณ ,
๋์ผํ ์ค์ ๊ฐ์ด๋ผ๋ฉด ์ค๋ณต๋ ๋งํผ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฐจ์งํ๊ณ ์๊ฒ๋๋ค.
์ ํ ์ ๋ณด์ ์ธ์คํด์ค๋ ์ค์ง ํ๋๋ง ์กด์ฌํด์ผํ๋ค. ์ด๋ด๋ ์ฌ์ฉ๋๋ ๊ฒ์ด ์ฑ๊ธํค ํจํด์ด๋ค.
์ฑ๊ธํค ํจํด์ด๋?
์ธ์คํด์ค๋ฅผ ์ค์ง ํ๋๋ง ์ ๊ณตํ๋ ํด๋์ค๋ฅผ ๋งํ๋ค
ํ๋์ ์ธ์คํด์ค๋ฅผ ์ฌ๋ฌ ๊ณณ์์ ๊ณต์ ํ์ฌ ์ฌ์ฉํ๋ค. (๊ณต์ ํ๋ ๋งํผ ๋์์ฑ ๋ฌธ์ ๋ ๊ณ ๋ คํด์ผํ๋ค!)
์ฅ์
- new๊ฐ ์๋ staticํ ์ธ์คํด์ค๋ฅผ ์์ฑํ์ฌ ๊ณ ์ ๋ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ๊ฐ์ง๊ฒ๋๋ค. ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น๋ฅผ ๋ฐฉ์งํ ์ ์๋ค
- ์ฑ๊ธํค ์ธ์คํด์ค๋ ์ ์ญ์ผ๋ก ๋ง๋ค์ด์ง๊ธฐ ๋๋ฌธ์, ์ฌ๋ฌ ๊ณณ์์ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ ์ ์๋ค.
- ์ธ์คํด์ค์ 2๋ฒ์งธ ์ ๊ทผ๋ถํฐ๋ ๊ฐ์ฒด ๋ก๋ฉ์๊ฐ์ด ์ค์ด๋ ๋ค
๋จ์
- ์ฑ๊ธํค ์ธ์คํด์ค๊ฐ ๋๋ฌด ๋ง์ ์ญํ ์ ๊ฐ์ง๊ณ ์๊ฑฐ๋, ๋๋ฌด ๋ง์ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ๊ณ ์์ ๋์๋
์ธ์คํด์ค๋ค ๊ฐ์ ๊ฒฐํฉ๋๊ฐ ๋์์ ธ OCP(๊ฐ๋ฐฉ ํ์ ์์น)์ ์๋ฐฐํ ์ ์๋ค.
- ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์ ๋๊ธฐํ์ฒ๋ฆฌ๋ฅผ ๋์น๋ฉด ์ธ์คํด์ค๊ฐ 2๊ฐ๊ฐ ์์ฑ๋ ์ ์๋ค!!
- ๋์์ฑ ํด๊ฒฐ์ ์ํด ํ์ํ ์ฝ๋๊ฐ ๋ง๋ค.
๊ตฌํ๋ฐฉ๋ฒ
๋ฐฉ๋ฒ 1 : private ์์ฑ์์ static ๋ฉ์๋
์ธ๋ถ์์ new ํค์๋๋ก Settings ์ธ์คํด์ค๋ฅผ ๋ง๋ค ์ ์๋๋ก ์์ฑ์๋ฅผ private๋ก ์ง์ ํ๊ณ ,
์ฌ๋ฌ ๊ณณ์์ Settings์ ์ธ์คํด์ค๋ฅผ ๊ฐ์ ธ๊ฐ ์ฌ์ฉํ ์ ์๋๋ก getInstance()๋ฉ์๋๋ฅผ static ์ผ๋ก ์์ฑํ๋ค
public class Settings {
//private ์์ฑ์
private Settings() {}
//static ์ธ์คํด์ค
private static Settings instance;
//์ธ์คํด์ค ๋ฐํํ๋ static getter ๋ฉ์๋
public static Settings getInstance(){
if(instance == null){
instance = new Settings();
}
return instance;
}
}
--------------------------------------------------
Settings setting1 = Settings.getInstance();
Settings setting2 = Settings.getInstance();
System.out.println(setting1 == setting2);
//๊ฒฐ๊ณผ๊ฐ true
๋ฐฉ๋ฒ1์ ๋ฌธ์ ์
์น์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฒฝ์ฐ, ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์ด ์ด๋ฃจ์ด์ง๋ค.
์ค๋ ๋A๊ฐ getInstance()์ if๋ฌธ์ ํต๊ณผํ์ฌ new Settings()๋ฅผ ํตํด ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ธฐ ์ด์ ์
์ค๋ ๋B๊ฐ getInstance()์ if๋ฌธ์ ํต๊ณผํ์ฌ new Settings()๋ฅผ ํตํด ์ธ์คํด์ค๋ฅผ ์์ฑํด์ผ๊ฒ ๋ค! ๋ผ๊ณ ํ๋ฉด
๊ฒฐ๊ณผ์ ์ผ๋ก ์ค๋ ๋A์ ์ค๋ ๋B๊ฐ ๊ฐ์ง instance๋ ์๋ก ๋ค๋ฅธ instance๊ฐ ๋์ด๋ฒ๋ฆฐ๋ค.
์ฑ๊ธํค์ ๋ฌด์กฐ๊ฑด instance๊ฐ 1๊ฐ๋ง ์กด์ฌํด์ผํ๋ค.
์ค๋ ๋A๊ฐ getInstance() ๋ฉ์๋์ ์ ๊ทผํ๋ฉด ์ค๋ ๋B๊ฐ getInstance()์ ์ ๊ทผํ์ง ๋ชปํ๊ฒ ํ ์ ์์๊น?
๋ฐฉ๋ฒ 2 : getInstance๋ฅผ ๋๊ธฐํ(synchronized)์ฒ๋ฆฌํ๋ค.
synchronized ํค์๋๋ ํ๋ฒ์ ํ๋์ ์ค๋ ๋๋ง ์ ๊ทผ์ ํ์ฉํ๊ฒ๋๋ค.
๋๋ฌธ์ ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์ ๋์์ฑ ๋ฌธ์ ์์ด ์ฑ๊ธํค์ ๋ณด์ฅํ ์ ์๊ฒ๋๋ค.
public class Settings {
//private ์์ฑ์
private Settings() {}
//static ์ธ์คํด์ค
private static Settings instance;
//์ธ์คํด์ค ๋ฐํํ๋ static getter ๋ฉ์๋
public static synchronized Settings getInstance(){ //๐ฅ
if(instance == null){
instance = new Settings();
}
return instance;
}
}
๋ฐฉ๋ฒ2์ ๋ฌธ์ ์
synchronized ํค์๋๋ ๋ด๋ถ์ ์ผ๋ก block/unblock ์ฒ๋ฆฌํ์ฌ ํ๋์ ์ค๋ ๋๋ง ์ ๊ทผํ ์ ์๊ฒ ํ๋๋ฐ,
์ด block/unblock ์์ ์ ๋น์ฉ์ด ๋น์ผํธ์ด๋ผ ์ฑ๋ฅ์ด์๊ฐ ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ๋๋ค.
๋ฉํฐ์ค๋ ๋ํ๊ฒฝ์์ ์์ ํ๊ฒ ์ต์ ํํ๋ ๋ฐฉ๋ฒ์ ์์๊น?
๋ฐฉ๋ฒ 3 : ์ด๋ฅธ ์ด๊ธฐํ(eager initialization)์ ์ฌ์ฉํ๋ค
์ฌ์ค Settings๊ฐ ํ๋๋ฐ์ ์์ด์ผํ๋ค๋ฉด ๊ฐ์ฒด์ ์ธ์คํด์ค๋ฅผ ๋ฏธ๋ฆฌ ๋ง๋ค๊ณ ,
๋ณ๊ฒฝ ๋ถ๊ฐ๋ฅํ๊ฒ finalํค์๋๋ฅผ ๋ถ์ฌ์๋ ํด๊ฒฐํ ์ ์๋ค.
getInstance๋ฅผ ํธ์ถํ๋ ์์ ์ ๊ฐ์ฒด ์กด์ฌ ์ฌ๋ถ๋ฅผ ํ์ธํ๊ณ , ์์ฑํ๋ if๋ฌธ๋ ๊ตณ์ด ์์ด๋ ๋๋ ๊ฒ์ด๋ค.
๋ํ ์ด๋ฏธ ๋ง๋ค์ด์ ธ์๋ ์ธ์คํด์ค๋ฅผ ๋ฐํ๋ง ํด์ฃผ๋ฉด ๋๋ ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์๋ ์์ ํ๊ฒ ์ฌ์ฉํ ์ ์๋ค!
public class Settings {
//private ์์ฑ์
private Settings() {}
//static final ์ธ์คํด์ค
private static final Settings instance = new Settings(); //๐ฅ
//์ธ์คํด์ค ๋ฐํํ๋ static getter ๋ฉ์๋
public static Settings getInstance(){ //๐ฅ
return instance;
}
}
๋ฐฉ๋ฒ3์ ๋ฌธ์ ์
Settings๊ฐ ์์ฃผ ๋ฌด๊ฑฐ์ด ๊ฐ์ฒด์ด๋ฉด ์ด๋จ๊น??
์ ํ๋ฆฌ์ผ์ด์ ๋ก๋ฉ ์์ ์ ๋ง์ ์์์ ํ ์ ํ์ฌ Settings์ ์ธ์คํด์ค๋ฅผ ๋ง๋ค์๋๋ฐ
์ฌ์ฉ๋๋ ๋น๋๊ฐ ๊ทธ๋ ๊ฒ ๋์ง ์๋ค๋ฉด(์ฐ์ง ์๋ ๊ฒฝ์ฐ๋ ํฌํจ) ์ด๋ฅธ ์ด๊ธฐํ๊ฐ ์คํ๋ ค ๋ ์ด ๋ ์ ์๋ค.
๋ฐฉ๋ฒ 4 : ํจ์จ์ ์ธ synchronized block : double checked locking
๋ฐฉ๋ฒ 3๋ฒ๊ณผ ๋ฌ๋ฆฌ ์ธ์คํด์ค๋ฅผ ๋์ค์ ๋ง๋ค๊ณ ์ถ๋คํ๋ฉด
๋ฐฉ๋ฒ 2๋ฒ์ synchronized ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋, double checked locking๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ฉด ๋๋ค
์ธ์คํด์ค ๋ณ์์ volatile ํค์๋๋ฅผ ์ฌ์ฉํ๋๋ฐ
volatile์ ์ฌ๋ฌ ์ค๋ ๋์์ ์ ๊ทผํ๋ ๋ณ์์ ๊ฐ์ ํญ์ ์ต์ ๊ฐ์ผ๋ก ์ฝ๊ฒํด์ค๋ค.
(๋ฉ์ธ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ์ฐธ์กฐํ๋ฏ๋ก ๋ค๋ฅธ ์ค๋ ๋์์๋ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ์ฐธ์กฐํ๊ฒ๋จ)
public class Settings {
//private ์์ฑ์
private Settings() {}
//static volatile ์ธ์คํด์ค
private static volatile Settings instance;
//์ธ์คํด์ค ๋ฐํํ๋ static getter ๋ฉ์๋
public static Settings getInstance(){ //๐ฅ
if(instance == null){
synchronized (Settings.class){
if(instance == null){
instance = new Settings();
}
}
}
return instance;
}
}
์ด ๋ฐฉ๋ฒ์ ๋งค๋ฒ synchronized ์ฒ๋ฆฌ๊ฐ ๋์ง ์๋๋ค.
๋๋ฌผ๊ฒ ๋์์ ์ ๊ทผํ ๋ฉํฐ์ค๋ ๋์ ๊ฒฝ์ฐ์๋ง synchronized ์ฒ๋ฆฌ๊ฐ ์ผ์ด๋๊ธฐ ๋๋ฌธ์
๋ฐฉ๋ฒ 2์์ ๊ฑฑ์ ํ๋ synchronized ํค์๋์ ๋น์ฉ์ฒ๋ฆฌ๊ฐ ํจ์ฌ ์ค์ด๋ค์๋ค.
๋ํ ์ธ์คํด์ค๋ฅผ ๋ฏธ๋ฆฌ ๋ง๋ค์ด๋๋ ๊ฒ์ด ์๋, ํธ์ถํ๋ ์์ ์์์ผ ์ธ์คํด์ค๊ฐ ๋ง๋ค์ด์ง๊ธฐ ๋๋ฌธ์
๋ฐฉ๋ฒ 3์์ ๊ฑฑ์ ํ๋ ์ด๋ฅธ ์ด๊ธฐํ์ ๋ฌธ์ ๋ ํด๊ฒฐํ ์ ์๊ฒ๋์๋ค.
๋ฐฉ๋ฒ4์ ๋ฌธ์ ์
volatile ํค์๋๋ฅผ ์ ์ฌ์ฉํ๋์ง, ์ ๋ฐ์ ์ธ ๋ฉ๋ชจ๋ฆฌ์ ๋ํ ํ์ต๊ณก์ ์ด ์๋ค
๋ฐฉ๋ฒ 5 : static inner ํด๋์ค ์ฌ์ฉํ๊ธฐ (๊ฐ์ฅ ๊ถ์ฅํ๋ ๋ฐฉ๋ฒโ)
๊ฐ์ฅ ๊ถ์ฅํ๋ ๋ฐฉ๋ฒ์ค์ ํ๋์ด๋ค.
๋ํ ๊ฐ์ฅ ๊ฐ๋จํ๊ฒ Thread-safeํ ์ฑ๊ธํค์ ๊ตฌํํ ์ ์๋ ์ฝ๋์ด๋ค.
ํด๋์ค์ ๋ก๋ฉ ๋ฐ ์ด๊ธฐํ๋ ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ ์๋ํด๋ ์ค์ง ํ๋ฒ๋ง ์ํ๋๋ค.
= ์ฑ๊ธํค ๋ณด์ฅ
SettingsHolderํด๋์ค๋ฅผ static inner class๋ก ์ ์ธํ๊ธฐ ๋๋ฌธ์
SettingsHolderํด๋์ค๋ SettingsHolder.instance๋ก ํธ์ถ๋๋ ์์ ์ ์ด๊ธฐํ๊ฐ ์ผ์ด๋๋ค.
= lazy loading ๋ณด์ฅ
public class Settings {
//private ์์ฑ์
private Settings() {}
//private static inner class
private static class SettingsHolder{ //๐ฅ
private static final Settings instance = new Settings();
}
//static getter
public static Settings getInstance(){ //๐ฅ
return SettingsHolder.instance;
}
}
๐ฅํท๊ฐ๋ฆฌ์ง ๋ง์!
์ ๊น.. static์ jvm์ด ์ฌ๋ผ๊ฐ๋ ์ ๋ถ ์ด๊ธฐํ๋๋๊ฒ์ด ์๋๊ฐ?!
๋ก๋ฉ์ ์ด๊ธฐํ์ ์ฐจ์ด๊ฐ ์๊ธฐ๋๋ฌธ์ด๋ค.
๋ก๋ฉ ? ํด๋์ค ํ์ผ์ ๋ฐ์ดํธ์ฝ๋๋ก ์ฝ์ด์ ๋ฉ๋ชจ๋ฆฌ๋ก ๊ฐ์ ธ์จ๋ค
์ด๊ธฐํ ? ์ํผ ํด๋์ค ๋ฐ ์ ์ ํ๋๋ฅผ ์ด๊ธฐํํ๋ค
๊ฐ๋จํ ์๊ธฐํ๋ฉด ํด๋์ค ๋ก๋ฉ์์๋ ์๋์ ๊ฐ๋ค
1. Settings(outer) ํด๋์ค ๋ก๋ฉ&์ด๊ธฐํ
SettingsHolder(inner) ํด๋์ค ๋ก๋ฉ
2. SettingsHolder.instace ํธ์ถํ๋ฉฐ SettingsHolder(inner) ํด๋์ค ์ด๊ธฐํO
(์ฐธ๊ณ https://kdhyo98.tistory.com/70)
์ฑ๊ธํค์ ๊นจํธ๋ฆฌ๋ ๋ฐฉ๋ฒ
์ฌ์ค.. ์ธ๋ถ์์ ์ฑ๊ธํค์ ์ ์งํ ์ ์๋ ๋ฐฉ๋ฒ์ ์์ฑ์๋ฅผ privateํ๊ฒ ์ ์ธํ์ฌ ๋ง๋ ๋ฐฉ๋ฒ ๋ฐ์๋ ์๋ค.
๋ฆฌํ๋ ์ , ์ง๋ ฌํ&์ญ์ง๋ ฌํ ํ๋ค๋ฉด ์ฑ๊ธํค์ ๊นจํธ๋ฆด ์ ์๋ค!
- ์ง๋ ฌํ&์ญ์ง๋ ฌํ
- ์ญ์ง๋ ฌํ๋ Object readResolve() ๋ฅผ ์ฌ์ฉํด์ ์ฑ๊ธํค์ด ๊นจ์ง๋ ๊ฒ์ ๋ง์ ์ ์๋ค
- ๋ฆฌํ๋ ์
- Enum์ ์ฌ์ฉํ์ฌ ๋ง์ ์ ์๋ค
- ์๋ฐ ์์ฒด์์ Enum์ ๋ฆฌํ๋ ์ ์ ๋ง๊ณ ์๊ธฐ๋๋ฌธ
- ์ง๋ ฌํ&์ญ์ง๋ ฌํ ํด๋ ๋์ผํ ์ธ์คํด์ค๋ก ๊ฐ์ฃผํ๋ค.
- ์ฅ์ & ๋จ์ : ํด๋์ค ๋ก๋ฉ ์ ๋ฏธ๋ฆฌ ๋ง๋ค์ด์ง๋ค๋ ๊ฒ!
- Enum์ ์ฌ์ฉํ์ฌ ๋ง์ ์ ์๋ค
'๐ฐ Design Pattern' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Adapter Pattern | ์ด๋ํฐํจํด (0) | 2022.08.14 |
---|---|
Prototype Pattern | ํ๋กํ ํ์ ํจํด (0) | 2022.08.14 |
Abstract Factory | ์ถ์ ํฉํ ๋ฆฌ ํจํด (0) | 2022.08.14 |
Factory Method Pattern | ํฉํ ๋ฆฌ ๋ฉ์๋ ํจํด (0) | 2022.07.29 |
[๊ฐ์ฒด ์์ฑ ํจํด] ์ ์ธต์ ์์ฑ์ ํจํด โ ์๋ฐ๋น ํจํด โ Builder ํจํด, lombok @Builder ์ฌ์ฉ๋ฐฉ๋ฒ ๋ฐ ์ฃผ์์ (0) | 2022.01.29 |