์ค๋์ ์ฑ๊ธํดํจํด์ ๋ํด ์์๋ณผ ๊ฒ์ ๋๋ค.

ํ๋ก ํธ์๋์์ ๋์์ธ ํจํด์ด๋ ๋ฐ๋ณต์ ์ผ๋ก ๋ฐ์ํ๋ ๋ฌธ์ ๋ฅผ ํจ๊ณผ์ ์ผ๋ก ํด๊ฒฐํ๊ธฐ ์ํ "๊ฒ์ฆ๋ ์ฝ๋ ๊ตฌ์กฐ๋ ์ค๊ณ ๋ฐฉ์"์ ์๋ฏธํฉ๋๋ค.
์ฆ, ์ด๋ค ๊ธฐ๋ฅ์ด๋ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค ๋ ์ข ๋ ๋์ ์ค๊ณ์ ์ ์ง๋ณด์๋ฅผ ์ํด ์ฌ์ฉํ ์ ์๋
"์ฝ๋ฉ ๋ฐฉ์์ ์ ์"์ด๋ผ๊ณ ํ ์ ์์ต๋๋ค.
๋ง๋ก๋ง ๋ค์ด์๋ ์ด๋ค ๊ฑธ ์๋ฏธํ๋์ง ์๋ฟ์ง ์๊ธฐ๋ ํฉ๋๋ค.
์๋ ์ค๋ช ๊ณผ ์์ ์ฝ๋๋ฅผ ๋ณด๋ฉฐ 1. ์ฑ๊ธํด ํจํด์ ๋ํด ์์๋ด ์๋ค.
ํ๋ก ํธ์๋ ๊ฐ๋ฐ ์ค๋ฌด์์๋ ์ด๋ป๊ฒ ์ ์ฉํ๋ฉด ์ข์์ง๋ ๊ฐ์ด ์์๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
์ฑ๊ธํด ํจํด (Singleton Pattern)
์ฑ๊ธํด ํจํด์ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋จ ํ๋์ ์ธ์คํด์ค๋ง ์กด์ฌํ๋๋ก ๋ณด์ฅํ๋ ์์ฑ ํจํด(Creational Pattern)์ ๋๋ค.
์ฃผ๋ก *ํ๊ฒฝ ์ค์ , ์ฑ์ ์ ์ญ ์ํ, ๊ณต์ฉ ๋ฆฌ์์ค ๋ฑ์ ํ ๊ณณ์์ ๊ด๋ฆฌํด์ผ ํ ๋ ์ฌ์ฉ๋ฉ๋๋ค.
์ฌ๊ธฐ์ ์ ๊น! ์ ํ๊ฒฝ์ค์ , ์ฑ ์ ์ญ, ๊ณต์ฉ๋ฆฌ์์ค์ ์ฌ์ฉํ ๊น?
1. ์ผ๊ด๋ ์ํ ๊ด๋ฆฌ
์: ๋ก๊ทธ์ธ ์ํ, ์ฌ์ฉ์ ์ค์ , ํ ๋ง, ์ธ์ด ๋ฑ์ด๋ฐ ์ ๋ณด๋ ์ฑ ์ ์ฒด์์ ์ผ๊ด๋๊ฒ ์ ์ง๋์ด์ผ ํฉ๋๋ค.
์ฌ๋ฌ ์ปดํฌ๋ํธ์์ ๋์ผํ ์ ๋ณด๊ฐ ํ์ํ๋ฐ,๊ฐ๊ฐ์ ์ปดํฌ๋ํธ๊ฐ ์ด ์ ๋ณด๋ฅผ ๋ฐ๋ก ๊ด๋ฆฌํ๋ฉด ๋ฐ์ดํฐ ๋ถ์ผ์น, ๋ฒ๊ทธ ๋ฐ์ ๊ฐ๋ฅ์ฑ์ด ํฝ๋๋ค.
๐ Singleton ํจํด์ผ๋ก ํ๋์ ์ ์ญ ์ธ์คํด์ค์์ ๊ด๋ฆฌํ๋ฉด ํญ์ ๋์ผํ ์ํ๋ฅผ ์ฐธ์กฐํ ์ ์์ต๋๋ค.
2. ๋ถํ์ํ ์ค๋ณต ์ ๊ฑฐ
๊ณต์ฉ ๋ฆฌ์์ค (์: API ์ธ์คํด์ค, DB ์ปค๋ฅ์ , WebSocket ์ฐ๊ฒฐ ๋ฑ)๋ํ๋๋ง ์์ผ๋ฉด ๋๋๋ฐ ์ฌ๋ฌ ๊ฐ ๋ง๋ค๋ฉด
๋ฉ๋ชจ๋ฆฌ ๋ญ๋น์ฑ๋ฅ ์ ํ๋ถํ์ํ ๋คํธ์ํฌ ํธ๋ํฝ ์ ๋ฐ ๊ฐ๋ฅ์ฑ
๐ ์ด๋ฐ ๊ฒฝ์ฐ์๋ ํ๋์ ์ธ์คํด์ค๋ง ์์ฑ๋๋๋ก ์ ํํ๋ Singleton ํจํด์ด ํจ๊ณผ์ ์ ๋๋ค.
3. ์ค์ ์ง์ค์ ๊ด๋ฆฌ → ์ ์ง๋ณด์ ํธ๋ฆฌ
ํ๊ฒฝ ์ค์ , ๊ณตํต ๋ก์ง, ์ ์ญ ์ํ ๋ฑ์ ์ฌ๊ธฐ์ ๊ธฐ ํฉ๋ฟ๋ ค๋๋ฉด…
๋์ค์ ์์ ํ๋ ค๋ฉด ๋ชจ๋ ํ์ผ์ ์ฐพ์๋ค๋ ์ผ ํจ์ค์๋ก ๋ค๋ฅธ ๊ณณ์์ ์ค์ ์ ๋ฎ์ด์ธ ์ ์์
๐ ์ ์ญ์์ ์ ๊ทผ ๊ฐ๋ฅํ ๋จ ํ๋์ ์ธ์คํด์ค๋ก ํต์ ํ๋ฉด,์ค์์์ ์ฝ๊ฒ ๊ด๋ฆฌํ๊ณ ์์ ์ฌํญ๋ ํ ๊ตฐ๋ฐ๋ง ๋ณ๊ฒฝํ๋ฉด ๋์ ๋๋ค.
4. ํด๋ผ์ด์ธํธ๊ฐ ๋์ด๋๋ ๋์ผํ ์ธ์คํด์ค๋ฅผ ๊ณต์
ํ๋ก ํธ์๋ ์ฑ์์๋ ์ฌ์ฉ์ ์ํธ์์ฉ์ ๋ฐ๋ผ ์ฌ๋ฌ ์ปดํฌ๋ํธ, ํ์ด์ง๊ฐ ๋์์ ์๊ธฐ๊ณ ์ฌ๋ผ์ง๋๋ค.
์ด๋๋ ๋งค๋ฒ ์ธ์คํด์ค๋ฅผ ์๋ก ์์ฑํ์ง ์๊ณ ํ๋์ ๊ณ ์ ๋ ์ธ์คํด์ค๋ฅผ ๊ณ์ ์ฌ์ฌ์ฉํ๋ฉด
๐ ์ฑ๋ฅ์ ์ด์ + ์ฝ๋ ๊ฐ ์ฐ๊ฒฐ์ฑ ์ ์ง
๊ทธ๋ผ ๋ค์ ๋ณธ๋ก ์ผ๋ก ๋์์์!
์ฑ๊ธํด ํจํด์ ํต์ฌ ๊ฐ๋ ์
1. ์ธ์คํด์ค๋ ๋จ ํ๋๋ง ์์ฑ๋๋ค.
2. ์ธ๋ถ์์ ์ง์ ์์ฑ์๋ฅผ ํธ์ถํ ์ ์๋ค.
3. ํญ์ ๋์ผํ ์ธ์คํด์ค๋ฅผ ๋ฐํํ๋ ์ ์ (static) ๋ฉ์๋๋ฅผ ์ ๊ณตํ๋ค.
์ผ๋จ ์ฝ๋๋ถํฐ ๋ณด๋ฉด์ ์ดํดํด๋ณผ๊ฒ์.
์๋ ์ฝ๋๋ ์ฑ๊ธํดํจํด์ Javascript ์์ ์ฝ๋์ ๋๋ค.
class Singleton {
constructor() {
if (Singleton.instance) {
return console.warn(
'Warning: Singleton class already instantiated'
);
}
Singleton.instance = this;
this.version = Date.now();
this.config = 'test';
}
static getInstance() {
if (!this.instance) {
this.instance = new Singleton();
}
return this.instance;
}
}
๊ตฌ์กฐ ์ค๋ช
- ์์ฑ์(private or ์ ํ์ ์ ๊ทผ)
- ์ธ์คํด์ค๋ฅผ ์ธ๋ถ์์ ์๋ก ๋ง๋ค์ง ๋ชปํ๋๋ก ๋ง์ต๋๋ค.
- ์ ์ ํ๋กํผํฐ(static instance)
- ์ธ์คํด์ค๋ฅผ ๋ฉ๋ชจ๋ฆฌ์ ํ ๋ฒ๋ง ์์ฑํ๊ณ ์ฌ์ฌ์ฉํฉ๋๋ค.
- ์ ์ ๋ฉ์๋(static getInstance)
- ์ธ์คํด์ค๋ฅผ ์ธ๋ถ์์ ์ ๊ทผํ ์ ์๊ฒ ํด์ค๋๋ค. ์๋ก์ด ์ธ์คํด์ค๋ฅผ ๋ง๋ค์ง ์๊ณ ๊ธฐ์กด ์ธ์คํด์ค๋ฅผ ๋ฐํํฉ๋๋ค
๊ทธ๋ผ ์ ์์ฑ๋ ์ฝ๋๋ฅผ ํธ์ถํด๋ณผ๊น์?
const s1 = new Singleton();
const s2 = new Singleton();
์ด๋ ๊ฒ ํธ์ถํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น์?
๊ฒฐ๊ณผ๋..
const s1 = new Singleton(); // ์ ์ ์์ฑ
const s2 = new Singleton(); // ๊ฒฝ๊ณ ๋ฐ์
Singleton { version: 1754567722799, config: 'test' }
Warning: Singleton class already instantiated
Singleton {}
์ฒซ๋ฒ์งธ ๊ฒฐ๊ณผ์๋ Singleton์ instance๊ฐ ๋์์ง๋ง, ๋๋ฒ์งธ ๊ฒฐ๊ณผ๋ Warning์ ๋ฑ์ผ๋ฉฐ,
์ธ์คํด์ค๋ฅผ ์ฐพ์ง ๋ชปํ๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
๊ทธ ์ด์ ๋
โ constructor๋ฅผ ์ง์ ํธ์ถํ๋ฉด ์ฑ๊ธํด์ ๊ท์น์ด ๊นจ์ง ์ ์์ต๋๋ค.
์ด ์์ ์์๋ ๊ฒฝ๊ณ ๋ง ๋์ฐ์ง๋ง, ์ค์ ๋ก๋ constructor๋ฅผ private ๋๋ protected๋ก ๋ง๋ค์ด ์์ ํ ์ฐจ๋จํ๋ ๊ฒ์ด ๋ ์์ ํฉ๋๋ค. (TypeScript ๋ฑ์์๋ private constructor ์ฌ์ฉ ๊ฐ๋ฅ)
๊ทธ๋ผ ์ด์ ์ ๋๋ก ํธ์ถ์ ํด๋ณด๊ฒ ์ต๋๋ค.
const s1 = Singleton.getInstance();
const s2 = Singleton.getInstance();
console.log(s1); // Singleton { version: ..., config: 'test' }
console.log(s2); // Singleton { version: ..., config: 'test' }
console.log(s1 === s2); // true
์ ์ฝ๋์ฒ๋ผ s1๊ณผ s2์ ๊ฒฐ๊ณผ๊ฐ์ด ๊ฐ์ผ๋ฉฐ, ๋๋ฑ๋น๊ต๋ฅผ ํด๋ true๊ฐ์ด ๋์ค๋ฉฐ ๋์ผํ ์ธ์คํด์ค๋ฅผ
๋ฐํํ๋ ๊ฒ์ ์ ์ ์๋ค์!
* ํญ์ getInstance()๋ฅผ ํตํด ๋์ผํ ์ธ์คํด์ค์ ์ ๊ทผํด์ผ ํฉ๋๋ค.
๋ณด์ ์ฌํญ
1. ์๋ฐ์คํฌ๋ฆฝํธ์์ ์์ฑ์ ์ฐจ๋จํ๋ ค๋ฉด?
- ์๋ฒฝํ ์ฐจ๋จ์ ๋ถ๊ฐ๋ฅํ์ง๋ง, ๊ด๋ก์ ์ผ๋ก ์ง์ ํธ์ถ์ ๊ธ์งํ๋ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
- TypeScript์์๋ private constructor๋ฅผ ํ์ฉํ์ฌ ๋ช ํํ๊ฒ ์ ์ดํ ์ ์์ต๋๋ค. ์๋๋ ํ์ ์คํฌ๋ฆฝํธ ์์ ์ฝ๋์ ๋๋ค.
class Singleton {
private static instance: Singleton;
private constructor() {
// ์ธ๋ถ์์ new Singleton()์ ์ ๋ ๋ชป ์
}
static getInstance(): Singleton {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
- private constructor: ์ธ๋ถ์์ new Singleton() ์ง์ ํธ์ถ ๋ถ๊ฐ
- Java, C# ๋ฑ ํด๋์ค ๊ธฐ๋ฐ ์ธ์ด์ ์ฑ๊ธํด๊ณผ ๊ฑฐ์ ์ ์ฌํ ๋ฐฉ์์ผ๋ก ์์ ํ๊ฒ ๊ตฌํ ๊ฐ๋ฅ
2. ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์ด๋ผ๋ฉด?
- Java, C++ ๊ฐ์ ์ธ์ด์์๋ ๋๊ธฐํ(Synchronized)๋ฅผ ๊ณ ๋ คํด์ผ ํฉ๋๋ค.
- JS๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฑ๊ธ ์ค๋ ๋์ด์ง๋ง, WebWorker๋ Node.js์์ ๋ฉํฐ ํ๋ก์ธ์ค๋ฅผ ์ธ ๊ฒฝ์ฐ ์ฃผ์๊ฐ ํ์ํฉ๋๋ค.
- -> ๋ฉํฐ์ค๋ ๋์์๋ ์ฌ๋ฌ ์ฐ๋ ๋๊ฐ ๋์์ getInstance()๋ฅผ ํธ์ถํ ์ ์๊ณ ๋ ๊ฐ ์ด์์ ์ธ์คํด์ค๊ฐ ์์ฑ๋ ๊ฐ๋ฅ์ฑ์ด ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
- Java, C++ ๋ฑ ๋ฉํฐ์ค๋ ๋ ์ธ์ด์์ ๋๊ธฐํ(Synchronization) ํ์
public class Singleton {
private static Singleton instance;
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
- synchronized: ํ ๋ฒ์ ํ๋์ ์ค๋ ๋๋ง ์ ๊ทผ ํ์ฉ
- Double-checked locking ๋ฑ์ ์ต์ ํ๋ ์ฌ์ฉํจ
๊ทธ๋ผ ์ฑ๊ธํดํจํด์ ์ฌ๊ธฐ๊น์ง ์์๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค!
์ฐธ๊ณ ์์: Youtube ์ฝ๋ฉ๋ฌธ