
[Java] ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ(OOP) - 3. ๋์์ธ ํจํด์ด๋?
3) ๋์์ธ ํจํด์ด๋? ๐ง ๋ฐ๋ณต๋๋ ์ค๊ณ ๋ฌธ์ ์ ๋ํ ๊ฒ์ฆ๋ “์ด๋ฆ ์๋ ํด๋ฒ”์ ์นดํ๋ก๊ทธ์ฅ์ : ๊ณตํต ์ดํ ์ ๊ณต(์์ฌ์ํต↑), ์ฌ์ฌ์ฉ์ฑ↑, ์ ์ง๋ณด์์ฑ↑์ฃผ์: “ํจํด ์ ์ฉ์ ์ํด ๋ฌธ์ ๋ฅผ ์ต์ง๋ก
lxvxxu.tistory.com
๐งฉ ๋์์ธ ํจํด โฅ — ์ฑ๊ธํค(Singleton) ํจํด
“๊ฐ์ฒด๋ฅผ ๋จ ํ๋๋ง ๋ง๋ค๊ณ , ์ด๋์๋ ๋์ผํ ์ธ์คํด์ค๋ฅผ ์ฐ์!”
๐ฏ ํ์ต ๋ชฉํ
- ํ๋ก๊ทธ๋จ ์ ์ฒด์์ ํ๋์ ๊ฐ์ฒด๋ง ์ฌ์ฉํ๋๋ก ๋ณด์ฅํ๋ ๋ฐฉ๋ฒ์ ์ดํดํ๋ค.
- ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์ ์์ ํ ์ฑ๊ธํค ๊ตฌํ ๋ฐฉ๋ฒ์ ๋ฐฐ์ด๋ค.
๐ง ์ฑ๊ธํค ํจํด์ด๋?
ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ์ค์ง ํ ๊ฐ๋ง ๋ง๋ค๊ณ , ์ ์ญ์ ์ผ๋ก ์ ๊ทผํ ์ ์๊ฒ ํ๋ ํจํด
๐ ์ ์
Ensure a class only has one instance, and provide a global point of access to it.
| ์ด๋ฆ | ์ฑ๊ธํค(Singleton) |
| ๋ฌธ์ | ์ฌ๋ฌ ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ฉด ์ํ ๊ด๋ฆฌ๊ฐ ์ด๋ ค์ |
| ํด๊ฒฐ | ๊ฐ์ฒด ์์ฑ์ ์ค์์์ ๊ด๋ฆฌ |
| ๊ฒฐ๊ณผ | ๊ฐ์ฒด๊ฐ 1๊ฐ๋ง ์กด์ฌํ์ฌ ์ผ๊ด๋ ์ํ ์ ์ง |
๐งฉ ๊ธฐ๋ณธ ๊ตฌํ๋ฒ
๐งฑ ๊ณ ์ ์ ์ธ ์ฑ๊ธํค ๊ตฌํ ๋ฐฉ์
public class Printer {
private static Printer printer = null; // ์ ์ผํ ์ธ์คํด์ค ์ ์ฅ ๊ณต๊ฐ
private Printer() { } // ์์ฑ์ ๋น๊ณต๊ฐ
public static Printer getPrinter() {
if (printer == null) {
printer = new Printer();
}
return printer;
}
public void print(String str) {
System.out.println(str);
}
}
public class User {
private String name;
public User(String name) { this.name = name; }
public void print() {
Printer printer = Printer.getPrinter();
printer.print(this.name + " print using " + printer.toString());
}
}
โก๏ธ ๋ชจ๋ User ๊ฐ์ฒด๊ฐ ๊ฐ์ Printer ์ธ์คํด์ค๋ฅผ ๊ณต์ ํจ.
โ ๏ธ ๋ฌธ์ ์ — ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ
๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์๋ ๋์์ ์ฌ๋ฌ ์ค๋ ๋๊ฐ getPrinter()๋ฅผ ํธ์ถํ ๊ฒฝ์ฐ
์ฌ๋ฌ ๊ฐ์ ์ธ์คํด์ค๊ฐ ์์ฑ๋ ์ ์์.
3-thread print using Printer@6653aac1
4-thread print using Printer@1deddeb6
→ ์๋ก ๋ค๋ฅธ ์ธ์คํด์ค ์ฌ์ฉ!
๐งฐ ํด๊ฒฐ์ฑ
1๏ธโฃ ์ ์ ์ด๊ธฐํ ๋ฐฉ์
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() { }
public static Singleton getInstance() {
return instance;
}
}
โ ์์ ํ์ง๋ง, ํ๋ก๊ทธ๋จ ์์ ์ ๋ฌด์กฐ๊ฑด ์ธ์คํด์ค๊ฐ ๋ง๋ค์ด์ง (๋นํจ์จ ๊ฐ๋ฅ)
2๏ธโฃ ๋๊ธฐํ ๋ฐฉ์ (Synchronized)
public class Singleton {
private static Singleton instance;
private Singleton() { }
public static synchronized Singleton getInstance() {
if (instance == null) instance = new Singleton();
return instance;
}
}
โ
Thread-safe
โ ๋๊ธฐํ๋ก ์ธํด ์ฑ๋ฅ ์ ํ ๊ฐ๋ฅ
3๏ธโฃ DCL (Double-Checked Locking)
Java 5 ์ด์์์ ๊ถ์ฅ๋๋ ๊ณ ๊ธ ๋ฐฉ๋ฒ
public class Singleton {
private volatile static Singleton instance;
private Singleton() { }
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
๐งฉ volatile → ์บ์ ๋์ ๋ฉ๋ชจ๋ฆฌ์์ ์ง์ ์ฝ์
๐งฉ synchronized → ๋์์ ํ ์ค๋ ๋๋ง ์ ๊ทผํ๋๋ก ๋ฝ(lock) ๊ฑธ๊ธฐ
๐ซ ์ฌ๋ก 2 — ์ด์ฝ๋ฆฟ ๊ณต์ฅ ์ ์ด ์์คํ
์ด์ฝ๋ฆฟ๊ณผ ์ฐ์ ๋ฅผ ํผํฉํ๊ณ ๋์ด๋ ๋ณด์ผ๋ฌ(Boiler) ๋ ๋ฐ๋์ ํ ๊ฐ๋ง ์กด์ฌํด์ผ ํ๋ค.
public class ChocolateBoiler {
private static ChocolateBoiler uniqueInstance;
private boolean empty;
private boolean boiled;
private ChocolateBoiler() {
empty = true;
boiled = false;
}
public static ChocolateBoiler getInstance() {
if (uniqueInstance == null)
uniqueInstance = new ChocolateBoiler();
return uniqueInstance;
}
// fill(), boil(), drain() ๋ฑ ๋ณด์ผ๋ฌ ์ ์ด ์ฝ๋...
}
โ
๋จ ํ๋์ ๋ณด์ผ๋ฌ๋ง ์กด์ฌํ๋ฏ๋ก
“์ค๋ณต ์์
”, “๋ฐ์ดํฐ ๋ถ์ผ์น” ๋ฑ์ ๋ฐฉ์งํ ์ ์์.
๐ ์ ๋ฆฌ
| ํต์ฌ ๊ฐ๋ | ๊ฐ์ฒด๋ฅผ ํ๋๋ง ๋ง๋ค๊ณ , ์ ์ญ์ ์ผ๋ก ์ ๊ทผ |
| ์ฅ์ | ์์ ๋ญ๋น ๋ฐฉ์ง, ๋ฐ์ดํฐ ์ผ๊ด์ฑ ์ ์ง |
| ๋จ์ | ํ ์คํธ ์ด๋ ค์, ๋ณ๋ ฌ ์ฒ๋ฆฌ ์ ์ฃผ์ ํ์ |
| ๋ํ ์์ | Logger, ์ค์ ๊ด๋ฆฌ์, Connection Pool ๋ฑ |