๋์์ธ ํจํด์ ๋ฌด์์ธ๊ฐ?
๋์์ธ ํจํด์ ์ํํธ์จ์ด ์ค๊ณ์ ์์ด ๊ณตํต๋ ๋ฌธ์ ๋ค์ ๋ํ ํ์ค์ ์ธ ํด๋ฒ๊ณผ ์๋ช ๋ฒ์ ์ ์ํ ์ฑ ์ด๋ค. ์ด ๋ถ์ผ์ ์์ด, ์ฌ์ธ๋ฐฉ์ด๋ผ๊ณ ๋ถ๋ฆฌ๋ Erich Gamma, Richard Helm, Ralph Jonhson, John Vlissides๊ฐ ์์ฑํ๊ธฐ์ Gang of Four(GoF)๋ผ๊ณ ๋ถ๋ฆฌ๊ณค ํ๋ค.
์ฆ, ๋์์ธ ํจํด์ ํ๋ก๊ทธ๋จ์ ๊ฐ๋ฐํ๋ ๊ณผ์ ์์ ์ฐ๋ฆฌ ์์ ๋์ฌ์ง ๋น์ทํ ๋ฌธ์ ๋ค์ ํด๊ฒฐํ๊ธฐ ์ํด ์ผ๋ จ์ "ํจํด"์ ๋ง๋ค์ด ์ฝ๊ฒ ํด๊ฒฐํ ์ ์๋๋ก ํ ๊ฒ์ด๋ค. ์ด๋ฅผ ์ ์์งํ๊ณ ํ์ฉํ๋ค๋ฉด ๋ง์ ์๊ฐ๊ณผ ๋ ธ๋ ฅ์ ์ค์ผ ์ ์์ ๊ฒ์ด๋ค.
๊ทธ๋ฌํ ํจํด์ ํฌ๊ฒ ์ฉ๋์ ๋ฐ๋ผ ์์ฑ ํจํด(Creational Patterns), ๊ตฌ์กฐ ํจํด(Structural Patterns), ํ๋ ํจํด(Behavioral Pattern)์ผ๋ก ๋๋๋ค.
๐ก ์์ฑ ํจํด์ ๊ฐ์ฒด ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ํจํด์ผ๋ก ํด๋ผ์ด์ธํธ๊ฐ ์์ฑํด์ผ ํ๋ ๊ฐ์ฒด ์ธ์คํด์ค ์ฌ์ด์ ์ฐ๊ฒฐ์ ๋์ด์ฃผ๋ ํจํด์ด๋ค.
๐ก๊ตฌ์กฐ ํจํด์ ํด๋์ค์ ๊ฐ์ฒด๋ฅผ ๋ ํฐ ๊ตฌ์กฐ๋ก ๋ง๋ค ์ ์๊ฒ ๊ตฌ์ฑ์ ์ฌ์ฉํ๋ ํจํด์ด๋ค.
๐กํ๋ ํจํด์ ํด๋์ค์ ๊ฐ์ฒด๋ค์ด ์ํธ์์ฉํ๋ ๋ฐฉ๋ฒ๊ณผ ์ญํ ์ ๋ถ๋ดํ๋ ๋ฐฉ๋ฒ์ ๋ค๋ฃจ๋ ํจํด์ด๋ค.
๋ฌผ๋ก ํจํด์ด ์ด๋ ๋ถ๋ฅ์ ์ํ๋ ์ง ์๋ ๊ฒ๋ ์ค์ํ์ง๋ง, ํจํด์ด ์ ํํ ์ด๋ค ์ญํ ์ ํ๋ ์ง ์ดํดํ๋ ๊ฒ์ด ์ค์ํ๋ค๊ณ ๋ณธ๋ค.
Creational Design Patterns
์์ฑ ํจํด์ ๊ฐ์ฒด์ ์์ฑ๊ณผ ๊ด๋ จ๋ ํจํด์ ๋ค๋ฃจ๋ฉฐ ์บก์ํ๋ ์ ์ฐ์ฑ์๋ ์ฝ๋๋ฅผ ๋ชฉํ๋ก ๋๋ค. ์ด๋ฌํ ํจํด์๋ ๋ํ์ ์ผ๋ก ์๋์ ๊ฐ๋ค.
- Factory method
- Abstract factory
- Builder
- Prototype
- Singleton
- ...
Singleton pattern(์ฑ๊ธํค ํจํด)
๋์์ธ ํจํด ์ค์์๋ ๊ฐ๋ ์ ์ผ๋ก๋ ๊ฐ์ฅ ๊ฐ๋จํ ์ฑ๊ธํค ํจํด์ด๋ค.
๋ฌผ๋ก , ๊ฐ๋จํ ๋งํผ ์ด๋ ๊ฒฝ์ฐ์ ์ด๋ค ์ฝ๋๋ก ์์ฑํด์ผ ํ๋ ์ง ๋ชจ๋ฅด๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ ์ ๋๋ก ์์ง ๋ชปํ๊ณ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค๊ณ ํ๋ค. ๊ทธ๋ ๊ธฐ์ ๋ฉด์ ์ด๋ ์์ผ๋ก์ ๊ฐ์ฒด ์งํฅ์ ๊ธฐ๋ณธ์ ์ดํดํ๊ธฐ ์ํด์ ์ ๋๋ก ํ์ ํด๋ณด์.
์ฑ๊ธํค ํจํด์ ๋จ ํ๋์ ์ ์ผํ ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ธฐ ์ํ ์ฝ๋ ํจํด์ด๋ค.
๊ทธ ๋ชฉ์ ์ ๋ฉ๋ชจ๋ฆฌ ์ ์ฝ์ ์ํ ๊ฒ์ด๊ณ , ๋์ผํ ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ์๋กญ๊ฒ ์ธ์คํด์ค๋ฅผ ์์ฑํ์ง ์๋๋ค. ์ด๋ ๋ง์น ์ ์ญ ๋ณ์์ ์ ์ฌํ๊ฒ ์๋ํ๋ค. ์ด๋์๋ ์ง ์ก์ธ์ค๋ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
๋ฐ๋ผ์ ์ฑ๊ธํค ํจํด์ด ์ ์ฉ๋ ๊ฐ์ฒด๋ ๋์ฒด์ ์ผ๋ก ๋ฆฌ์์ค๋ฅผ ๋ง์ด ์ฐจ์งํ๋ ์ญํ ์ผ ๋ ์ฌ์ฉํ๋ค. ๊ฐ๋ น ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ชจ๋์ ๊ทธ ์๋ก ๋ค ์ ์๋ค. ์ด ๊ณผ์ ์์ ๋ฐ์ํ๋ I/O๋ฐ์ด๋๋ ๋ฌด๊ฑฐ์ด ์์ ์ ์ํ๊ณ , ๊ตณ์ด ์ฌ๋ฌ ๋ฒ ๋ง๋ค ํ์๋ ์๊ธฐ ๋๋ฌธ์ด๋ค.
์ด ์ธ์๋ ๋์คํฌ ์ฐ๊ฒฐ, ๋คํธ์ํฌ ํต์ , DBCP ์ปค๋ฅ์ ํ, ์ค๋ ๋ ํ, ์บ์, ๋ก๊ทธ ๊ธฐ๋ก ๊ฐ์ฒด ๋ฑ ๋ฆฌ์์ค๋ฅผ ๋ง์ด ์ฐจ์งํ๋ ๊ฐ์ฒด์์ ์ฌ์ฉํ๋ค.
์ฑ๊ธํค ํจํด์ ์ด๋ป๊ฒ ๋ง๋๋๋ฐ?
๋ง๋๋ ๋ฐฉ๋ฒ์ ๊ฐ๋จํ์ง๋ง ์๊ฐ๋ณด๋ค ์ฌ๋ฌ ๋ฐฉ๋ฒ์ด ์๋ค. ๊ทธ ์ฝ๋ ๊ธฐ๋ฒ์ ํฌ๊ฒ 7๊ฐ์ง๋ก ๋๋๋ฉฐ ์ด๋ ์ํฉ์ ๋ง๊ฒ ์ฌ์ฉํด์ผํ๋ค.
- Eager Initalization
- Static block initialization
- Lazy Iinitialization
- Thread safe initialization
- Double-Checked Locking
- Bill Pugh Solution
- Enum ์ด์ฉ
๋ญ ๊ฐ๋จํ๋ค๋ฉด์ ์์ฒญ ๋ง๋ค? ๋ผ๊ณ ์๊ฐํ ์ ์๋ค. ๋ง๊ธด ํด๋ ์ฌ๊ธฐ์ ์๊ฐํ ๊ฒ์ Lazy Initialization๋ฟ์ด๋ฉฐ, ๋ค๋ฅธ ๋ถ๋ถ๋ค์ ๊ตฌ๊ธ์ด๋ ๊ด๋ จ ๋ฌธ์๋ฅผ ์ฐพ์๋ณด๋ฉด ๊ต์ฅํ ๋ง์ผ๋ฏ๋ก ์ฐพ์๋ณด๊ธธ ๋ฐ๋๋ค. ์ฐ๋ฆฌ๋ ํจํด ์์ฒด๋ฅผ ์ดํดํ๋ ๊ฒ์ ๋ชฉ์ ์ ๋๊ธฐ ๋๋ฌธ์ด๋ค. ๋ฌผ๋ก ์๋ฐ ๊ฐ๋ฐ์๋ผ๋ฉด, ์ฑ๊ธํค ๊ตฌํ ๋ฐฉ๋ฒ 7๊ฐ์ฏค(?)์ ๊ฐ๋ณ๊ฒ ํ์ตํ๋ ๊ฑธ ๊ถ์ฅํ๋ค.
์ฌ์ค ์ 7๊ฐ๋ ์์์๋ถํฐ ๊ฐ ๋จ์ ์ ๋ณด์ํ๋ฉฐ ๋์จ ๊ฒ์ด๋ค. ๊ทธ๋์ ๋ฐ๋ก ํ์ฉ์ ํด์ผ ํ๋ค๋ฉด Bill Pugh Solution๊ณผ Enum์ ๋ํ ์ด์ฉ ์์ ๋ฅผ ํ์ตํ๋ ๊ฒ์ด ์ข๋ค.(์ธ์ ๊น์ง๋ Lazy Initialzation์ด ์ดํดํ๊ธฐ ์ข์ผ๋ฉฐ, ์๋ฃ๋ ๋ง๊ธฐ ๋๋ฌธ์ด๋ค.)
๊ทธ๋์ ์๊ฐํ Lazy Initialization์ ํน์ง์ ์๋์ ๊ฐ๋ค.
๐ฒ ๊ฐ์ฒด ์์ฑ์ ๋ํ ๊ด๋ฆฌ๋ฅผ ๋ด๋ถ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ค.
๐ฒ ๋ง๋ค์ด์ง ์ธ์คํด์ค๊ฐ null์ธ์ง ์๋์ง ์ฌ๋ถ์ ๋ฐ๋ผ ์ด๊ธฐํ/๋ฐํํ๋ค.
๐ฒ ๋จ, ์ฐ๋ ๋ ์ธ์ดํ(Thread Safe)ํ์ง ์๋๋ค.
โ ์ ์ฐ๋ ๋ ์ธ์ดํ ํ์ง ์๋๊ฐ?
์๋ฐ๋ ๋ฉํฐ ์ฐ๋ ๋ ์ธ์ด์ธ๋ฐ, ์ด ํ๊ฒฝ์์๋ ์ฐ๋ ๋ ์ธ์ดํํ์ง ์๋๋ค.
๋ฉํฐ์ฐ๋ ๋ ์ธ์์ ์ฌ๋ฌ ์ฐ๋ ๋์์ ๋์์ ์ ๊ทผํ๋ฉด ๋์์ null ์ฒดํฌ๋ฅผ ํ๊ฒ ๋๋ค. ์ด๋ก์ธํด ๋์์ ์คํ๋๋ ์ฐ๋ ๋๋ค์์ null ์ฒดํฌ์ ๋ํ ๊ฒ์ฌ๊ฐ ๋ ๋ฒ์ด์ ํต๊ณผ๋๋ ์น๋ช ์ ์ธ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
๊ทธ๋ ๊ฒ ๋๋ฉด ์ธ์คํด์ค๊ฐ ๋ ๊ฐ ์ด์ ์๊ธฐ๊ณ , ์ด๋ ์ฑ๊ธํค ํจํด์ ๋ถํฉํ์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.
์ด์ ๋ํ C++ ์ฝ๋ ์์๋ฅผ ์ดํด๋ณด์.
class Singleton
{
public:
Singleton(Singleton &other) = delete;
void operator=(const Singleton &) = delete;
static Singleton *GetInstance(const std::string &value)
{
if (instance_ == nullptr)
instance_ = new Singleton(value);
return instance_;
}
std::string value() const { return value_; }
private:
Singleton(const std::string value) : value_(value) {}
static Singleton *instance_;
std::string value_;
};
Singleton *Singleton::instance_ = nullptr;
int main()
{
Singleton *instance1 = Singleton::GetInstance("First");
Singleton *instance2 = Singleton::GetInstance("Second");
std::cout << instance1->value() << std::endl; // fisrt
std::cout << instance2->value() << std::endl; // first
return 1;
}
๐ฒ `delete`๋ฅผ ํตํด์ copy๊ฐ ๋ ๊ฐ๋ฅ์ฑ์ ๋ง๋๋ค. ์ด๋ ์ธ์คํด์ค๊ฐ ์ ์ผํด์ผํ๊ธฐ ๋๋ฌธ์ด๋ค.
๐ฒ instance๊ฐ nullptr์ธ์ง ํ์ธํด์ฃผ๊ณ , nullptr์ด๋ฉด ์๋กญ๊ฒ ์์ฑํด์ฃผ๊ณ ๋ฆฌํดํด์ค๋ค.
๐ฒ ์ค์ ์์ฑ์๋ class ๋ด๋ถ์ private๋ก ์ ์ธํด์ค๋ค. ๋ฐ๋ผ์ ์ธ๋ถ์์ ์ ๊ทผํ ์ ์๋ค.
๐ฒ ์ด๊ธฐ์ ์ธ์คํด์ค๋ nullptr๋ก ์ ์ธํด์ฃผ์ด์ผ ํ๋ค. ์ด๋ ํด๋์ค ๋ฐ์์ ํด์ฃผ์ด์ผ ํ๋ค.
๋ฐ๋ผ์ ์ธ์คํด์ค๋ฅผ ๋๋ฒ ์์ฑํด์ฃผ๋ ค๋ ํด๋น ์ฝ๋๋ ์ฒซ๋ฒ์งธ ์ธ์คํด์ค๋ฐ์ ์ฌ์ฉํ ์ ๋ฐ์ ์๋ค.
์๋ ๊ทธ๋ฆผ์ ํตํด์ ์ฑ๊ธํค์ ๋ํ ๊ตฌ์กฐ๋ฅผ ์ฝ๊ฒ ์ดํดํด๋ณด์.

๋ฐ์ค์ static, : ๋ค์๋ ํ์ ๋ช ์
์ฑ๊ธํค ํจํด์ ๋ฌด์กฐ๊ฑด ์ข์ ๊ฒ์ธ๊ฐ?
๋น์ฐํ ์๋๋ค. ๋ฌผ๋ก DB ์ปค๋ฅ์ ํ๊ฐ์ด ๊ณตํต๋ ๊ฐ์ฒด๋ฅผ ์ฌ๋ฌ๊ฐ ์์ฑํ๊ฑฐ๋, ๋ฆฌ์์ค๋ฅผ ๋ง์ด ์ฐจ์งํ๋ ๊ฐ์ฒด์ ๊ฒฝ์ฐ์๋ ์ด์ ๋ ๋ง๋ค. ํ์ง๋ง, ์ฑ๊ธํค์ ๊ทธ ํน์ง ์์ฒด๋ง์ผ๋ก ์ป์ ์ ์๋ ๋ถ์ด์ต๋ ๋ง๋ค.
1. ๋ชจ๋๊ฐ์ ์์กด์ฑ ์ฆ๊ฐ
์ฑ๊ธํค์ ์์ ๋ฐฐ์ ๋ฏ์ด ๋ฏธ๋ฆฌ ์์ฑํ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ค. ์ด๋ ๋ชจ๋๋ค๊ฐ์ ๊ฐํ ์์กด์ฑ์ ๋ถ๋ฌ์ผ์ผํจ๋ค. ์ฌ๋ฌ ๋ชจ๋๋ค์์ ์ฑ๊ธํค์ ์ ์ฉํ ๋์ผํ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ค๊ณ ํด๋ณด์. ์ด๋ ์ด ์ฑ๊ธํค ๊ฐ์ฒด๊ฐ ๋ฐ๋๋ฉด ๋๋จธ์ง ๋ชจ๋๋ค๋ ์ ๋ถ ์์ ์ด ํ์ํ ๊ท์ฐฎ์ ์ํฉ์ด ๋ฐ์ํ ๊ฒ์ด๋ค.
์ฆ, ์ฑ๊ธํค ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ฉด, ๋ถํ์ํ๊ฒ ์์ ์ ํด์ผํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ด ์๊ฒจ ์ข์ง ๋ชปํ๋ค.
2. SOLID ์์น ์๋ฐฐ ๊ฐ๋ฅ์ฑ
์ธํฐํ์ด์ค์ ๊ฐ์ ์ถ์ํ์ ์์กดํ๋ ๊ฒ์ด ์๋, ๊ตฌ์ฒด ํด๋์ค์ ์์กดํ๋ ๊ฒ์ ์์กด ์ญ์ ์์น(DIP)์ ์๋ฐ๋๋ค. ๋ํ ์ฑ๊ธํค ์์ฒด๊ฐ ๋๋ฌด ๋ง์ ์ฑ ์์ ์ง๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ ๋จ์ผ ์ฑ ์ ์์น(SRP)์๋ ๋ถํฉํ์ง ์์ ์ ์๋ค. ๊ทธ๋ฆฌ๊ณ ์์ ๋ณธ ๋ชจ๋๊ฐ์ ์์กด์ฑ ์ฆ๊ฐ๋ ๊ณง, ํด๋์ค๋ค ๊ฐ์ ๊ฒฐํฉ๋๊ฐ ๋๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค. ์ด๋ ๊ฐ๋ฐฉ-ํ์ ์์น(OCP)์๋ ์๋ฐฐ๋๋ค.
๋ฟ๋ง ์๋๋ผ ํ ์คํธ ์ฝ๋๋ฅผ ์ง๊ธฐ ํ๋ค๋ค๋ ๋จ์ ๋ ์กด์ฌํ๋ค. ์ด๋ ๋ฏ, ์ฑ๊ธํค ํจํด์ ๊ทธ ์ฅ์ ๋งํผ์ด๋ ๋จ์ ๋ ๋ง์ ํจํด์ด๋ค.
โ์์์ ๊ด๋ฆฌํด์ฃผ๋ Spring ์ปจํ ์ด๋
์ฐ๋ฆฌ๊ฐ ์ง์ ๋ง๋๋ ๊ฒ๋ณด๋จ, ๋ฏธ๋ฆฌ ๋ง๋ค์ด์ ธ ์๋ ํ๋ ์์ํฌ์ ๋์์ ๋ฐ๋ ๊ฒ์ด ํจ์ฌ ์ข๋ค. ์์ ๋งํ๋ ์ฑ๊ธํค์ ๋จ์ ์ ์ ๋ถ ๋ณด์ํด์ฃผ๊ธฐ ๋๋ฌธ์ด๋ค.
์ด๋ Spring ์ปจํ ์ด๋๊ฐ ๊ฐ๊ฐ์ ๊ฐ์ฒด๋ฅผ ์ ๋ถ ์ฑ๊ธํค์ผ๋ก ์กด์ฌํ ์ ์๋๋ก ๊ด๋ฆฌํด ์ฃผ๋ฉฐ, ํด๋์ค ์ ์ด๋ฅผ ์ปจํ ์ด๋๊ฐ ๋งก๋ IoC ๋ฐฉ์์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ด๋ค.
Builder Pattern(๋น๋ ํจํด)
์์ฑ ํจํด์ ์ผ์ข ์ธ ๋น๋ ํจํด์ ๊ธฐ์กด์ ์์ฑ์์์ ํน์ฑ ๊ฐ์ด ๋๋ฌด ๋ง์ ๋ ์ฌ์ฉํ ์ ์๋ ๊ธฐ๋ฒ์ด๋ค.
๊ทธ๋์ ๋์ผํ ํ๋ก์ธ์ค๋ฅผ ๊ฑฐ์ณ ๋ค์ํ ๊ตฌ์ฑ์ ์ธ์คํด์ค๋ฅผ ๋ง๋ค ์ ์๋ค.

์ฌ์ง์์๋ ๋ณด๋ ๋ฐ์ ๊ฐ์ด House๋ฅผ ๋ง๋๋๋ฐ์ ์ผ๋ฐ์ ์ธ ์์ฑ์(constructor)๋ฅผ ์ฌ์ฉํ๋ค๊ณ ์๊ฐํด๋ณด์. new ์ฐ์ฐ์๋ฅผ ํตํด์ ์ธ์คํด์ค๋ฅผ ์์ฑํด์ฃผ๊ณ , ์๋ ๊ฐ์ ๋ํด์๋ null๋ก ๋ฃ์ด์ฃผ์๋ค. ์ด๋ ์ง๊ด์ ์ด์ง ์๋ค. true๋ผ๊ณ ์ ํ์๋ ๋ถ๋ถ์ด ์ด๋ ํ๋กํผํฐ๋ฅผ ๊ฐ๋ฆฌํค๋์ง ์์๋ณด๊ธฐ๋ ํ๋ค๋ค.
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ Solution์ผ๋ก ๋น๋ ํจํด์ ์ฌ์ฉํ ์ ์๋ค.
๋น๋ ํจํด์ ๋๊ฒจ์ฃผ์ด์ผ ํ๋ ์ธ์์ ์์๋ฅผ ์งํฌํ์๊ฐ ์์ผ๋ฉฐ Optionalํ ๋ฐ์ดํฐ๋ฅผ ์ ๋ถ ์ ์ด์ค ํ์๋ ์๋ค.
์ ๋ฆฌํ์๋ฉด, ๋น๋ ํจํด์ Optionalํ ๋ฐ์ดํฐ์ ๋ํ ์ฒ๋ฆฌ๋ฅผ ์ผ์ผ์ด ํด์ฃผ์๋ ๊ธฐ์กด์ ์์ฑ์์ ๋จ์ ์ ๋ณด์ํ๊ธฐ ์ํด ์ฌ์ฉํ๋ค.
๋น๋ ํจํด์ ๊ตฌ์กฐ
์์ ์ค๋ช ํ ๋น๋ ํจํด์ ์๋ฐํ ๊ตฌ๋ถ์ ์ง์๋ฉด Simple ๋น๋ ํจํด์ด๋ค. Simple ๋น๋ ํจํด์ ์ฝ๋์ ๊ฐ๋ ์ฑ, ์ผ๊ด์ฑ, ๊ทธ๋ฆฌ๊ณ ๋ถ๋ณ์ฑ์ ์ด์ ์ ๋๊ธฐ ๋๋ฌธ์ด๋ค.
Simple ๋น๋ ํจํด์ Effective Java(์ดํํฐ๋ธ ์๋ฐ)์์ ์๊ฐํ๋ ๋น๋ ํจํด์ด๋ค. ์ฐ๋ฆฌ๊ฐ ์ง๊ธ๋ถํฐ ์์์ผ ํ๋ ๊ฒ์ GOF ๋น๋ ํจํด์ด๋ค.
GOF์์ ์ ์ํ๊ณ ์๋ ๋น๋ ํจํด์ ๊ฐ์ฒด์ ์์ฑ ์๊ณ ๋ฆฌ์ฆ๊ณผ ์กฐ๋ฆฝ ๋ฐฉ๋ฒ์ ๋ถ๋ฆฌํ์ฌ ๋น๋ ๊ณต์ ์ ์์ฑํ๋ ๊ฒ์ ๋ชฉํ๋ก ํ๋ค. ๊ทธ๋์ ์ด ์กฐ๋ฆฝ ๋ฐฉ๋ฒ์ ์ ์ํ ํด๋์ค๋ฅผ Director๋ผ๊ณ ๋ถ๋ฅธ๋ค.
๊ฐ๋จํ๊ฒ ๊ฐ์ฒด๋ง ์์ฑํ๋ฉด ๋์ง, ์ ๊ตณ์ด ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ์๊ณ ๋ฆฌ์ฆ๊ณผ ์กฐ๋ฆฝ ๋ฐฉ๋ฒ์ ๋ถ๋ฆฌํ๋ ๊ฑธ๊น? ์ด๋ ์ฌ๋ฌ๊ฐ์ง ๋น๋ ํ์์ ์ ์ฐํ๊ฒ ์ฒ๋ฆฌํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.(์ ์ฐํ ๋น๋ ์ฒ๋ฆฌ)
Director ๋น๋ ํจํด ๊ตฌ์กฐ


์ค๋ฅธ์ชฝ๊ณผ ์ผ์ชฝ ๊ทธ๋ฆผ์ ๋์ผํ ๊ตฌ์กฐ์ด๋ฉฐ, ์์๋ง ๋ค๋ฅธ Director ํจํด ๊ตฌ์กฐ์ด๋ค.
๐ฒ Builder : ๋น๋ ์ถ์ ํด๋์ค
๐ฒ ConcreteBuilder : ๋น๋์ ๊ตฌํ์ฒด
๐ฒ Director : ๋น๋์์ ์ ๊ณตํ๋ ๋ฉ์๋๋ค์ ์ฌ์ฉํด์ ์์๋๋ก Product(ํน์ Car)๋ฅผ ์์ฑํ๋ ๊ณผ์ ์ ์ ์
๐ฒ Product/Car : Director๊ฐ Builder๋ก ๋ง๋ค์ด๋ธ ๊ฒฐ๊ณผ๋ฌผ
์กฐ๊ธ ๋ ์ฝ๊ฒ ์ดํดํด ๋ณด์๋ฉด, Director๋ ๋น๋ ์ถ์ ํด๋์ค์ธ Builder์ ๋ฉ์๋๋ค์ ํตํด์ Product๋ฅผ ๋ง๋ ๋ค๋ผ๊ณ ์๊ฐํ์. Director๊ฐ ๋ฐ๋ ์ธ์์ ๊ฐ์ ๊ตฌ์ฒดํ๋ Builder๊ฐ ๋๊ณ , ์ด๋ ConcreateBuilder์ผ ๊ฒ์ด๋ค. ๊ทธ๋ฆฌ๊ณ Director๋ Builder์์ ์ ๊ณตํ๋ ๋ฉ์๋๋ฅผ ํตํด์ ์ค์ Product๋ฅผ ๋ง๋ค ์ ์๋ ๊ฒ์ด๋ค.
๋ค์๋งํด, ๊ตฌ์ฒดํ๋ Builder๋ ๋ถํ์ ๋ง๋ค๊ณ , Director๋ ์ถ์ํ๋ Builder ํด๋์ค์ ๋ฉ์๋๋ฅผ ํตํด์ ์๋ง์ ์ ํ์ ๋ง๋ค ์ ์๋ค.
GOF ๋น๋ ํจํด์ C++์ผ๋ก(Simple ๋น๋ ํจํด)
#include <algorithm>
#include <iostream>
#include <sstream>
#include <vector>
class House {
private:
House(std::string name, bool has_roof, bool has_garage,
bool has_swimming_pool, bool has_garden, int num_of_doors)
: name_(name),
has_roof_(has_roof),
has_garage_(has_garage),
has_swimming_pool_(has_swimming_pool),
has_garden_(has_garage),
num_of_doors_(num_of_doors) {}
const std::string name_;
const bool has_roof_;
const bool has_garage_;
const bool has_swimming_pool_;
const bool has_garden_;
const int num_of_doors_;
friend HouseBuilder;
};
class HouseBuilder {
public:
void reset() {
name_ = "";
has_roof_ = false;
has_garden_ = false;
has_swimming_pool_ = false;
has_garden_ = false;
num_of_doors_ = 0;
}
HouseBuilder &SetName(std::string name) {
name_ = name;
return *this;
}
HouseBuilder &AddRoof() {
has_roof_ = true;
return *this;
}
HouseBuilder &AddGarage() {
has_garage_ = true;
return *this;
}
HouseBuilder &AddSwimmingPool() {
has_swimming_pool_ = true;
return *this;
}
HouseBuilder &AddGarden() {
has_garden_ = true;
return *this;
}
HouseBuilder &SetNumOfDoors(int n) {
num_of_doors_ = n;
return *this;
}
House *Build() {
return new House(name_, has_roof_, has_garage_, has_swimming_pool_,
has_garden_, num_of_doors_);
}
private:
std::string name_;
bool has_roof_;
bool has_garage_;
bool has_swimming_pool_;
bool has_garden_;
int num_of_doors_;
};
int main() {
HouseBuilder builder;
House *my_house = builder.SetName("my house")
.AddRoof()
.AddGarage()
.AddGarden()
.SetNumOfDoors(4)
.Build();
return 1;
}
๋น๊ต์ ๊ฐ๋จํ Simple ๋น๋ ํจํด์ผ๋ก ์ฝ๋๋ฅผ ๊ตฌํํด๋ณด์.
๐ฒ House ํด๋์ค๋ HouseBuilder๋ฅผ friend๋ก ๋์์ผ๋ฉฐ, ์์ฑ์๋ฅผ private๋ก ๋์๋ค. ์ฆ, HouseBuilder๋ง์ด House ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ ์๋ค.
๐ฒ friend๋ก ๋๋ ์ด์ ๋ ์ํ ์ฐธ์กฐ๋ฅผ ๋ง๊ธฐ ์ํจ์ด๋ค. ์ฆ, ์ด๋ฏธ ์์ฑํ ๊ฐ์ฒด์ ๋ํ ๋ณ๊ฒฝ์ด ์ด๋ฃจ์ด์ง๋ ๊ฒ์ ๋ง์ ์ ์๋ค.
๐ฒ .Build()๋ฅผ ํตํด ์ค์ ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ ์๋ค.
๐ฒ HouseBuilder&๋ ๋ ํผ๋ฐ์ค ๊ฐ์ ๊ฐ์ง๋ ๊ฒ์ผ๋ก, ์ฒด์ด๋ ๊ธฐ๋ฒ์ ํตํด์ ์ฐ์์ ์ผ๋ก ํ๋กํผํฐ์ ๋ํ ์ค์ ์ด ๊ฐ๋ฅํ๋ค.
โ ๏ธ ์๋ ์ฝ๋๋ ์ํ ์ฐธ์กฐ๊ฐ ์ผ์ด๋, ์ด๋ฏธ ์์ฑ๋ ๊ฐ์ฒด์ ํ๋กํผํฐ๊ฐ ๋ณ๊ฒฝ๋๋ ์๋ฐ ์ฝ๋ ์์์ด๋ค.
class Product {
public:
void setPropertyA(int value) {
propertyA = value;
}
void setPropertyB(int value) {
propertyB = value;
}
void displayProperties() {
std::cout << "Property A: " << propertyA << ", Property B: " << propertyB << std::endl;
}
private:
int propertyA;
int propertyB;
};
class ProductBuilder {
public:
void buildProduct() {
product = new Product();
}
void setPropertyA(int value) {
// ์ฌ๊ธฐ์ Product ๊ฐ์ฒด์ propertyA๋ฅผ ๋ณ๊ฒฝํ๋ ค๋ ์๋
product->setPropertyA(value);
}
void setPropertyB(int value) {
// ์ฌ๊ธฐ์ Product ๊ฐ์ฒด์ propertyB๋ฅผ ๋ณ๊ฒฝํ๋ ค๋ ์๋
product->setPropertyB(value);
}
Product* getResult() {
return product;
}
private:
Product* product;
};
int main() {
ProductBuilder builder;
builder.buildProduct(); // Product ๊ฐ์ฒด๋ฅผ ์์ฑ
// ์ฌ๊ธฐ์ ProductBuilder๊ฐ ์ด๋ฏธ ์์ฑํ Product ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๊ณ ๋ณ๊ฒฝํ๋ ค๋ ์๋
builder.setPropertyA(42);
builder.setPropertyB(64);
Product* finalProduct = builder.getResult();
finalProduct->displayProperties();
return 0;
}
Reference
Builder
Say you have a constructor with ten optional parameters. Calling such a beast is very inconvenient; therefore, you overload the constructor and create several shorter versions with fewer parameters. These constructors still refer to the main one, passing s
refactoring.guru
๐ ๋น๋(Builder) ํจํด - ์๋ฒฝ ๋ง์คํฐํ๊ธฐ
Builder Pattern ๋น๋ ํจํด(Builder Pattern)์ ๋ณต์กํ ๊ฐ์ฒด์ ์์ฑ ๊ณผ์ ๊ณผ ํํ ๋ฐฉ๋ฒ์ ๋ถ๋ฆฌํ์ฌ ๋ค์ํ ๊ตฌ์ฑ์ ์ธ์คํด์ค๋ฅผ ๋ง๋๋ ์์ฑ ํจํด์ด๋ค. ์์ฑ์์ ๋ค์ด๊ฐ ๋งค๊ฐ ๋ณ์๋ฅผ ๋ฉ์๋๋ก ํ๋ํ๋ ๋ฐ์
inpa.tistory.com
๐ ์ฑ๊ธํค(Singleton) ํจํด - ๊ผผ๊ผผํ๊ฒ ์์๋ณด์
Singleton Pattern ์ฑ๊ธํค ํจํด์ ๋์์ธ ํจํด๋ค ์ค์์ ๊ฐ์ฅ ๊ฐ๋ ์ ์ผ๋ก ๊ฐ๋จํ ํจํด์ด๋ค. ํ์ง๋ง ๊ฐ๋จํ ๋งํผ ์ด ํจํด์ ๋ํด ์ฝ๋๋ง ๋์ ธ์ฃผ๊ณ ๋๋ด๋ฒ๋ฆฌ๋ ๊ฒฝ์ฐ๊ฐ ์์ด, ์ด๋์ ์ฐ์ด๋์ง ์ด๋ ํ ๋ฌธ
inpa.tistory.com