Ver3.5 ๐๏ธ C++ ๋์์ธ ํจํด ์์ ์ ๋ณต

๐๏ธ C++ ๋์์ธ ํจํด ์์ ์ ๋ณต
Gang of Four ํจํด ๊ตฌํ๋ถํฐ ์ค์ ํ์ฉ๊น์ง, ์ง์ง ์ธ๋ชจ์๋ ๊ฐ์ด๋
Design Patterns ยท GoF ยท C++ Implementation
์ผ ์์งํ ๋งํ์๋ฉด... ๋์์ธ ํจํด ์ฒ์ ๋ค์์ ๋ "์ด๊ฒ ๋ญ ์๋ฆฌ์ผ?" ํ๋ ์ฌ๋ ๋๋ง ์๋์ง? ๐
๊ทผ๋ฐ ๋ง์ ๊ณต๋ถํ๊ณ ๋๋ฉด "์ ์ด๊ฑฐ ์์ด ์ด๋ป๊ฒ ์ฝ๋ฉํ์ง?" ์ถ์ด์ง๋ ๊ทธ ๋๋... ์ค๋ ๊ทธ ๋๋ ์ ๋๋ก ์ ๋ฌํด๋ณผ๊ฒ.
Gang of Four(GoF)๊ฐ 1994๋
์ ์ ๋ฆฌํ 23๊ฐ์ง ๋์์ธ ํจํด, C++๋ก ์ด๋ป๊ฒ ๊ตฌํํ๊ณ ์ด๋์ ์ฐ๋์ง ์์ ํํค์ณ๋ณด์๊ณ ! ๐ฅ
"Gang of Four"๋ 1994๋ Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides ์ด 4๋ช ์ด ์ด ์ฑ "Design Patterns: Elements of Reusable Object-Oriented Software"์์ ์ ๋ํ์ด. ์ด ์ฑ ์์ 23๊ฐ์ง ํจํด์ ์ ๋ฆฌํ๊ณ , ์ง๊ธ๋ ์ํํธ์จ์ด ๊ณตํ์ ๋ฐ์ด๋ธ๋ก ๋ถ๋ฆผ ในใ ๋ ์ ๋ ์ฑ ์ ใ ใ
์์ฑ ํจํด์ ๊ฐ์ฒด๋ฅผ ์ด๋ป๊ฒ ๋ง๋ค์ง์ ๋ํ ๊ณ ๋ฏผ์ ํด๊ฒฐํด์ค.
"๊ทธ๋ฅ new ์ฐ๋ฉด ๋๋ ๊ฑฐ ์๋?" ๋ผ๊ณ ์๊ฐํ ์ ์๋๋ฐ... ๊ทธ๊ฒ ๋ฌธ์ ์ ์์์ด๊ฑฐ๋ ใ
ใ
ใ
๊ฐ์ฒด ์์ฑ ๋ก์ง์ด ์ฌ๊ธฐ์ ๊ธฐ ํผ์ง๋ฉด ๋์ค์ ์์ ํ ๋ ์ง์ฅ์ ๋ง๋ณด๊ฒ ๋จ. ๊ทธ๋์ ์์ฑ ํจํด์ด ํ์ํ ๊ฑฐ์ผ!
ํต์ฌ ๊ฐ๋
: ํด๋์ค์ ์ธ์คํด์ค๊ฐ ๋ฑ ํ๋๋ง ์กด์ฌํ๋๋ก ๋ณด์ฅํ๊ณ , ์ ์ญ ์ ๊ทผ์ ์ ์ ๊ณตํ๋ ํจํด์ด์ผ.
๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ, ๋ก๊ทธ ์์คํ
, ์ค์ ๊ด๋ฆฌ์ ๊ฐ์ ๊ณณ์์ ์์ฃผ ์.
C++์์ Singleton ๊ตฌํํ ๋ ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ ๊ณ ๋ ค ์ ํ๋ฉด ์ง์ง ํฐ์ผ๋จ ๐ฑ
C++11๋ถํฐ๋ Meyers' Singleton์ด ๊ฐ์ฅ ์์ ํ๊ณ ๊น๋ํ ๋ฐฉ๋ฒ์ผ๋ก ์ธ์ ๋ฐ๊ณ ์์ด!
// โ
Meyers' Singleton - C++11 ์ดํ ๊ฐ์ฅ ์์ ํ ๋ฐฉ๋ฒ
#include <iostream>
#include <string>
class Logger {
public:
// ์ ์ ๋ฉ์๋๋ก ์ ์ผํ ์ธ์คํด์ค ๋ฐํ
static Logger& getInstance() {
static Logger instance; // C++11: ์ค๋ ๋ ์์ ๋ณด์ฅ!
return instance;
}
void log(const std::string& message) {
std::cout << "[LOG] " << message << std::endl;
}
// ๋ณต์ฌ ์์ฑ์์ ๋์
์ฐ์ฐ์ ์ญ์ (์ธ์คํด์ค ๋ณต์ฌ ๋ฐฉ์ง)
Logger(const Logger&) = delete;
Logger& operator=(const Logger&) = delete;
private:
Logger() {
std::cout << "Logger ์ด๊ธฐํ ์๋ฃ!" << std::endl;
}
~Logger() = default;
};
int main() {
Logger& logger1 = Logger::getInstance();
Logger& logger2 = Logger::getInstance();
logger1.log("์ฒซ ๋ฒ์งธ ๋ก๊ทธ ๋ฉ์์ง");
logger2.log("๋ ๋ฒ์งธ ๋ก๊ทธ ๋ฉ์์ง");
// ๊ฐ์ ์ธ์คํด์ค์ธ์ง ํ์ธ
std::cout << "๊ฐ์ ์ธ์คํด์ค? "
<< (&logger1 == &logger2 ? "YES โ
" : "NO โ")
<< std::endl;
return 0;
}
Singleton์ ์ ์ญ ์ํ๋ฅผ ๋ง๋ค์ด์ ํ ์คํธํ๊ธฐ ์ด๋ ต๊ฒ ๋ง๋ค ์ ์์ด. ๋จ์ฉํ๋ฉด ์ ๋๊ณ , ์ง์ง ํ์ํ ๊ฒฝ์ฐ์๋ง ์จ์ผ ํด. ํ์ ์์๋ "Singleton์ ์ํฐํจํด์ด๋ค"๋ผ๋ ๋ง๋ ์์ ์ ๋๋๊น ใ ใ ์ํฉ ๋ด๊ฐ๋ฉด์ ์จ์ผ ํจ!
ํต์ฌ ๊ฐ๋
: ๊ฐ์ฒด ์์ฑ์ ์๋ธํด๋์ค์ ์์ํ๋ ํจํด. ์ด๋ค ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ๋ง๋ค์ง๋ฅผ ์๋ธํด๋์ค๊ฐ ๊ฒฐ์ ํ๊ฒ ํด์ค.
"Open/Closed Principle" - ํ์ฅ์๋ ์ด๋ ค์๊ณ , ์์ ์๋ ๋ซํ์๋ ์ค๊ณ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํจ!
// ๐ญ Factory Method ํจํด ์์ - ๊ฒ์ ์บ๋ฆญํฐ ์์ฑ
#include <iostream>
#include <memory>
#include <string>
// ์ถ์ ์ ํ (Product)
class Character {
public:
virtual ~Character() = default;
virtual void attack() = 0;
virtual std::string getName() const = 0;
};
// ๊ตฌ์ฒด ์ ํ๋ค (Concrete Products)
class Warrior : public Character {
public:
void attack() override {
std::cout << getName() << ": ๊ฒ์ผ๋ก ๊ฐํ! โ๏ธ" << std::endl;
}
std::string getName() const override { return "์ ์ฌ"; }
};
class Mage : public Character {
public:
void attack() override {
std::cout << getName() << ": ํ์ด์ด๋ณผ ๋ฐ์ฌ! ๐ฅ" << std::endl;
}
std::string getName() const override { return "๋ง๋ฒ์ฌ"; }
};
class Archer : public Character {
public:
void attack() override {
std::cout << getName() << ": ํ์ด ๋ฐ์ฌ! ๐น" << std::endl;
}
std::string getName() const override { return "๊ถ์"; }
};
// ์ถ์ ์์ฑ์ (Creator)
class CharacterFactory {
public:
virtual ~CharacterFactory() = default;
// Factory Method - ์๋ธํด๋์ค์์ ๊ตฌํ
virtual std::unique_ptr<Character> createCharacter() = 0;
// ํ
ํ๋ฆฟ ๋ฉ์๋ - ์์ฑ ํ ๊ณตํต ์ฒ๋ฆฌ
void spawnCharacter() {
auto character = createCharacter();
std::cout << character->getName() << " ์บ๋ฆญํฐ ์ํ ์๋ฃ! ๐ฎ" << std::endl;
character->attack();
}
};
// ๊ตฌ์ฒด ์์ฑ์๋ค (Concrete Creators)
class WarriorFactory : public CharacterFactory {
public:
std::unique_ptr<Character> createCharacter() override {
return std::make_unique<Warrior>();
}
};
class MageFactory : public CharacterFactory {
public:
std::unique_ptr<Character> createCharacter() override {
return std::make_unique<Mage>();
}
};
int main() {
WarriorFactory warriorFactory;
MageFactory mageFactory;
warriorFactory.spawnCharacter();
mageFactory.spawnCharacter();
return 0;
}
ํต์ฌ ๊ฐ๋
: ๊ด๋ จ๋ ๊ฐ์ฒด๋ค์ ํจ๋ฐ๋ฆฌ(์ ํ๊ตฐ)๋ฅผ ์์ฑํ๋ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํด. Factory Method์ ์์ ๋ฒ์ ์ด๋ผ๊ณ ๋ณด๋ฉด ๋ผ.
UI ์ปดํฌ๋ํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ, ํฌ๋ก์ค ํ๋ซํผ ๊ฐ๋ฐ์์ ์์ฃผ ๋ฑ์ฅํจ!
// ๐จ Abstract Factory - UI ํ
๋ง ์์คํ
#include <iostream>
#include <memory>
#include <string>
// ์ถ์ ์ ํ๋ค
class Button {
public:
virtual ~Button() = default;
virtual void render() = 0;
};
class TextBox {
public:
virtual ~TextBox() = default;
virtual void render() = 0;
};
// ๋คํฌ ํ
๋ง ์ ํ๋ค
class DarkButton : public Button {
public:
void render() override {
std::cout << "๐ [๋คํฌ ๋ฒํผ] ์ด๋์ด ๋ฐฐ๊ฒฝ์ ํฐ ํ
์คํธ" << std::endl;
}
};
class DarkTextBox : public TextBox {
public:
void render() override {
std::cout << "๐ [๋คํฌ ํ
์คํธ๋ฐ์ค] ์ด๋์ด ์
๋ ฅ์ฐฝ" << std::endl;
}
};
// ๋ผ์ดํธ ํ
๋ง ์ ํ๋ค
class LightButton : public Button {
public:
void render() override {
std::cout << "โ๏ธ [๋ผ์ดํธ ๋ฒํผ] ๋ฐ์ ๋ฐฐ๊ฒฝ์ ๊ฒ์ ํ
์คํธ" << std::endl;
}
};
class LightTextBox : public TextBox {
public:
void render() override {
std::cout << "โ๏ธ [๋ผ์ดํธ ํ
์คํธ๋ฐ์ค] ๋ฐ์ ์
๋ ฅ์ฐฝ" << std::endl;
}
};
// ์ถ์ ํฉํ ๋ฆฌ
class UIFactory {
public:
virtual ~UIFactory() = default;
virtual std::unique_ptr<Button> createButton() = 0;
virtual std::unique_ptr<TextBox> createTextBox() = 0;
};
// ๊ตฌ์ฒด ํฉํ ๋ฆฌ๋ค
class DarkThemeFactory : public UIFactory {
public:
std::unique_ptr<Button> createButton() override {
return std::make_unique<DarkButton>();
}
std::unique_ptr<TextBox> createTextBox() override {
return std::make_unique<DarkTextBox>();
}
};
class LightThemeFactory : public UIFactory {
public:
std::unique_ptr<Button> createButton() override {
return std::make_unique<LightButton>();
}
std::unique_ptr<TextBox> createTextBox() override {
return std::make_unique<LightTextBox>();
}
};
// ํด๋ผ์ด์ธํธ ์ฝ๋
void renderUI(UIFactory& factory) {
auto button = factory.createButton();
auto textBox = factory.createTextBox();
button->render();
textBox->render();
}
int main() {
std::cout << "=== ๋คํฌ ํ
๋ง ===" << std::endl;
DarkThemeFactory darkFactory;
renderUI(darkFactory);
std::cout << "\n=== ๋ผ์ดํธ ํ
๋ง ===" << std::endl;
LightThemeFactory lightFactory;
renderUI(lightFactory);
return 0;
}
ํต์ฌ ๊ฐ๋
: ๋ณต์กํ ๊ฐ์ฒด๋ฅผ ๋จ๊ณ๋ณ๋ก ์์ฑํ๋ ํจํด. ์์ฑ์์ ๋งค๊ฐ๋ณ์๊ฐ ๋๋ฌด ๋ง์์ง ๋ ๊ตฌ์์ ์ญํ ์ ํด์ค!
"Telescoping Constructor" ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐ ์ต๊ณ ์ผ. ํ๋ C++์์๋ Fluent Interface ์คํ์ผ๋ก ๋ง์ด ์.
// ๐ Builder ํจํด - ๋ฒ๊ฑฐ ์ฃผ๋ฌธ ์์คํ
(Fluent Interface)
#include <iostream>
#include <string>
#include <vector>
class Burger {
public:
std::string bun; // ๋ฒ ์ข
๋ฅ
std::string patty; // ํจํฐ ์ข
๋ฅ
bool cheese = false; // ์น์ฆ ์ฌ๋ถ
bool lettuce = false; // ์์์ถ ์ฌ๋ถ
bool tomato = false; // ํ ๋งํ ์ฌ๋ถ
std::string sauce; // ์์ค
int pattyCount = 1; // ํจํฐ ๊ฐ์
void display() const {
std::cout << "\n๐ === ์ฃผ๋ฌธํ์ ๋ฒ๊ฑฐ ===" << std::endl;
std::cout << "๋ฒ: " << bun << std::endl;
std::cout << "ํจํฐ: " << patty << " x" << pattyCount << std::endl;
std::cout << "์น์ฆ: " << (cheese ? "โ
" : "โ") << std::endl;
std::cout << "์์์ถ: " << (lettuce ? "โ
" : "โ") << std::endl;
std::cout << "ํ ๋งํ : " << (tomato ? "โ
" : "โ") << std::endl;
std::cout << "์์ค: " << sauce << std::endl;
std::cout << "=====================" << std::endl;
}
};
class BurgerBuilder {
private:
Burger burger;
public:
BurgerBuilder& setBun(const std::string& bun) {
burger.bun = bun;
return *this; // ๋ฉ์๋ ์ฒด์ด๋์ ์ํด ์๊ธฐ ์์ ๋ฐํ
}
BurgerBuilder& setPatty(const std::string& patty, int count = 1) {
burger.patty = patty;
burger.pattyCount = count;
return *this;
}
BurgerBuilder& addCheese() {
burger.cheese = true;
return *this;
}
BurgerBuilder& addLettuce() {
burger.lettuce = true;
return *this;
}
BurgerBuilder& addTomato() {
burger.tomato = true;
return *this;
}
BurgerBuilder& setSauce(const std::string& sauce) {
burger.sauce = sauce;
return *this;
}
Burger build() {
return burger; // ์ต์ข
๊ฐ์ฒด ๋ฐํ
}
};
int main() {
// Fluent Interface๋ก ๋ฒ๊ฑฐ ์ฃผ๋ฌธ - ์ฝ๊ธฐ ์ฝ๊ณ ์ง๊ด์ !
Burger myBurger = BurgerBuilder()
.setBun("ํต๋ฐ ๋ฒ")
.setPatty("์๊ณ ๊ธฐ", 2)
.addCheese()
.addLettuce()
.addTomato()
.setSauce("ํน์ ์์ค")
.build();
myBurger.display();
// ๊ฐ๋จํ ๋ฒ๊ฑฐ๋ ์ฝ๊ฒ!
Burger simpleBurger = BurgerBuilder()
.setBun("์ผ๋ฐ ๋ฒ")
.setPatty("๋ญ๊ณ ๊ธฐ")
.setSauce("๋ง์๋ค์ฆ")
.build();
simpleBurger.display();
return 0;
}
C++์์ Builder ํจํด์ ์ธ ๋
return *this;๋ก ๋ฉ์๋ ์ฒด์ด๋์ ๊ตฌํํ๋ฉด ์ฝ๋๊ฐ ํจ์ฌ ์ฝ๊ธฐ ์ข์์ ธ. ์ด๊ฑธ "Fluent Interface"๋ผ๊ณ ํ๋๋ฐ, ์ฌ๋ฅ๋ท ๊ฐ์ ํ๋ซํผ์์ ๊ฐ๋ฐ ๊ด๋ จ ์ฌ๋ฅ์ ๊ณต์ ํ ๋๋ ์ด๋ฐ ํจํด ์ค๋ช
์ด ์ธ๊ธฐ ์๋๋ผ๊ณ ! ๐
ํต์ฌ ๊ฐ๋
: ๊ธฐ์กด ๊ฐ์ฒด๋ฅผ ๋ณต์ฌ(clone)ํด์ ์ ๊ฐ์ฒด๋ฅผ ๋ง๋๋ ํจํด. ๊ฐ์ฒด ์์ฑ ๋น์ฉ์ด ํด ๋ ์ ์ฉํด!
C++์์๋ ๋ณต์ฌ ์์ฑ์์ clone() ๋ฉ์๋๋ฅผ ํ์ฉํด์ ๊ตฌํํจ.
// ๐งฌ Prototype ํจํด - ๊ฒ์ ๋ชฌ์คํฐ ๋ณต์
#include <iostream>
#include <memory>
#include <string>
class Monster {
public:
virtual ~Monster() = default;
virtual std::unique_ptr<Monster> clone() const = 0; // ํต์ฌ!
virtual void display() const = 0;
std::string name;
int hp;
int attack;
};
class Goblin : public Monster {
public:
Goblin(const std::string& n, int h, int a) {
name = n; hp = h; attack = a;
}
// ๋ณต์ฌ ์์ฑ์ ๊ธฐ๋ฐ clone
std::unique_ptr<Monster> clone() const override {
return std::make_unique<Goblin>(*this);
}
void display() const override {
std::cout << "๐บ " << name << " | HP:" << hp << " | ATK:" << attack << std::endl;
}
};
class Dragon : public Monster {
public:
Dragon(const std::string& n, int h, int a) {
name = n; hp = h; attack = a;
}
std::unique_ptr<Monster> clone() const override {
return std::make_unique<Dragon>(*this);
}
void display() const override {
std::cout << "๐ " << name << " | HP:" << hp << " | ATK:" << attack << std::endl;
}
};
int main() {
// ์๋ณธ ๋ชฌ์คํฐ ์์ฑ (๋น์ฉ์ด ํฐ ์์
์ด๋ผ๊ณ ๊ฐ์ )
auto originalGoblin = std::make_unique<Goblin>("๊ณ ๋ธ๋ฆฐ ์", 100, 25);
// ๋ณต์ ๋ก ๋น ๋ฅด๊ฒ ์ฌ๋ฌ ๋ชฌ์คํฐ ์์ฑ!
auto goblin1 = originalGoblin->clone();
auto goblin2 = originalGoblin->clone();
// ๋ณต์ ๋ ๋ชฌ์คํฐ ์ปค์คํฐ๋ง์ด์ง
goblin1->name = "๊ณ ๋ธ๋ฆฐ ๋ณ์ฌ A";
goblin1->hp = 50;
goblin2->name = "๊ณ ๋ธ๋ฆฐ ๋ณ์ฌ B";
goblin2->hp = 60;
std::cout << "=== ๋ชฌ์คํฐ ๋ชฉ๋ก ===" << std::endl;
originalGoblin->display();
goblin1->display();
goblin2->display();
return 0;
}
๊ตฌ์กฐ ํจํด์ ํด๋์ค์ ๊ฐ์ฒด๋ฅผ ์ด๋ป๊ฒ ์กฐํฉํ ์ง์ ๋ํ ํด๋ต์ ์ค.
๋ ๊ณ ๋ธ๋ก์ฒ๋ผ ์ฌ๋ฌ ํด๋์ค๋ฅผ ์กฐํฉํด์ ๋ ํฐ ๊ตฌ์กฐ๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ด๋ผ๊ณ ์๊ฐํ๋ฉด ๋จ! ๐งฑ
ํต์ฌ ๊ฐ๋
: ํธํ๋์ง ์๋ ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ง ํด๋์ค๋ค์ด ํจ๊ป ๋์ํ ์ ์๋๋ก ํด์ฃผ๋ ํจํด.
110V ์ฝ์ผํธ์ 220V ํ๋ฌ๊ทธ ๊ฝ์ ๋ ์ด๋ํฐ ์ฐ๋ ๊ฑฐ๋ ๋๊ฐ์ ๊ฐ๋
์ ใ
ใ
// ๐ Adapter ํจํด - ๊ตฌํ ๊ฒฐ์ ์์คํ
์ฐ๋
#include <iostream>
#include <string>
// ์ ์์คํ
์ด ๊ธฐ๋ํ๋ ์ธํฐํ์ด์ค (Target)
class PaymentProcessor {
public:
virtual ~PaymentProcessor() = default;
virtual void processPayment(const std::string& amount) = 0;
};
// ๊ตฌํ ๊ฒฐ์ ์์คํ
(Adaptee) - ๋ณ๊ฒฝ ๋ถ๊ฐ๋ฅํ ๋ ๊ฑฐ์ ์ฝ๋
class LegacyPaymentSystem {
public:
void makePayment(double amount, const std::string& currency) {
std::cout << "๐ณ ๊ตฌํ ์์คํ
์ผ๋ก ๊ฒฐ์ : "
<< amount << " " << currency << std::endl;
}
};
// ์ด๋ํฐ - ๊ตฌํ ์์คํ
์ ์ ์ธํฐํ์ด์ค๋ก ๊ฐ์
class PaymentAdapter : public PaymentProcessor {
private:
LegacyPaymentSystem legacySystem;
public:
void processPayment(const std::string& amount) override {
// ๋ฌธ์์ด ๊ธ์ก์ ๊ตฌํ ์์คํ
ํ์์ผ๋ก ๋ณํ
double numericAmount = std::stod(amount);
legacySystem.makePayment(numericAmount, "KRW");
std::cout << "โ
์ด๋ํฐ๋ฅผ ํตํด ๊ฒฐ์ ์๋ฃ!" << std::endl;
}
};
// ํด๋ผ์ด์ธํธ ์ฝ๋ - ์ ์ธํฐํ์ด์ค๋ง ์๋ฉด ๋จ
void checkout(PaymentProcessor& processor, const std::string& amount) {
std::cout << "๊ฒฐ์ ์ฒ๋ฆฌ ์ค..." << std::endl;
processor.processPayment(amount);
}
int main() {
PaymentAdapter adapter;
checkout(adapter, "50000");
return 0;
}
ํต์ฌ ๊ฐ๋
: ๊ฐ์ฒด์ ๋์ ์ผ๋ก ์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ ํจํด. ์์๋ณด๋ค ์ ์ฐํ ๊ธฐ๋ฅ ํ์ฅ ๋ฐฉ๋ฒ!
C++ STL์ ์คํธ๋ฆผ ์์คํ
์ด ์ด ํจํด์ ์ฌ์ฉํ๊ณ ์์ด. ifstream์ ๋ฒํผ๋ง, ์ํธํ ๋ฑ์ ์ถ๊ฐํ๋ ๊ฒ์ฒ๋ผ!
// โ Decorator ํจํด - ์ปคํผ ์ฃผ๋ฌธ ์์คํ
#include <iostream>
#include <memory>
#include <string>
// ๊ธฐ๋ณธ ์ปดํฌ๋ํธ ์ธํฐํ์ด์ค
class Coffee {
public:
virtual ~Coffee() = default;
virtual std::string getDescription() const = 0;
virtual double getCost() const = 0;
};
// ๊ธฐ๋ณธ ์ปคํผ (Concrete Component)
class Espresso : public Coffee {
public:
std::string getDescription() const override {
return "์์คํ๋ ์";
}
double getCost() const override { return 2000.0; }
};
class Americano : public Coffee {
public:
std::string getDescription() const override {
return "์๋ฉ๋ฆฌ์นด๋
ธ";
}
double getCost() const override { return 3000.0; }
};
// ๋ฐ์ฝ๋ ์ดํฐ ๊ธฐ๋ณธ ํด๋์ค
class CoffeeDecorator : public Coffee {
protected:
std::unique_ptr<Coffee> coffee;
public:
CoffeeDecorator(std::unique_ptr<Coffee> c) : coffee(std::move(c)) {}
};
// ๊ตฌ์ฒด ๋ฐ์ฝ๋ ์ดํฐ๋ค
class MilkDecorator : public CoffeeDecorator {
public:
MilkDecorator(std::unique_ptr<Coffee> c)
: CoffeeDecorator(std::move(c)) {}
std::string getDescription() const override {
return coffee->getDescription() + " + ์ฐ์ ๐ฅ";
}
double getCost() const override {
return coffee->getCost() + 500.0;
}
};
class SyrupDecorator : public CoffeeDecorator {
private:
std::string syrupType;
public:
SyrupDecorator(std::unique_ptr<Coffee> c, const std::string& syrup)
: CoffeeDecorator(std::move(c)), syrupType(syrup) {}
std::string getDescription() const override {
return coffee->getDescription() + " + " + syrupType + "์๋ฝ๐ฏ";
}
double getCost() const override {
return coffee->getCost() + 700.0;
}
};
class WhipDecorator : public CoffeeDecorator {
public:
WhipDecorator(std::unique_ptr<Coffee> c)
: CoffeeDecorator(std::move(c)) {}
std::string getDescription() const override {
return coffee->getDescription() + " + ํํํฌ๋ฆผ๐ฆ";
}
double getCost() const override {
return coffee->getCost() + 800.0;
}
};
int main() {
// ์๋ฉ๋ฆฌ์นด๋
ธ + ์ฐ์ + ๋ฐ๋๋ผ์๋ฝ + ํํํฌ๋ฆผ
std::unique_ptr<Coffee> myOrder = std::make_unique<Americano>();
myOrder = std::make_unique<MilkDecorator>(std::move(myOrder));
myOrder = std::make_unique<SyrupDecorator>(std::move(myOrder), "๋ฐ๋๋ผ");
myOrder = std::make_unique<WhipDecorator>(std::move(myOrder));
std::cout << "โ ์ฃผ๋ฌธ: " << myOrder->getDescription() << std::endl;
std::cout << "๐ฐ ๊ฐ๊ฒฉ: " << myOrder->getCost() << "์" << std::endl;
return 0;
}
ํต์ฌ ๊ฐ๋
: ๋ณต์กํ ์๋ธ์์คํ
์ ๋ํ ๋จ์ํ๋ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๋ ํจํด.
"์ค๋งํธํ ์ฑ ํ๋๋ก ์กฐ๋ช
, ์์ด์ปจ, TV ๋ค ์ ์ดํ๋ ๊ฒ"๊ณผ ๊ฐ์ ๊ฐ๋
์ด์ผ!
// ๐ Facade ํจํด - ํ์์ดํฐ ์์คํ
#include <iostream>
// ๋ณต์กํ ์๋ธ์์คํ
๋ค
class Projector {
public:
void on() { std::cout << "๐ฝ๏ธ ํ๋ก์ ํฐ ์ผ์ง" << std::endl; }
void setInput(const std::string& input) {
std::cout << "๐ฝ๏ธ ์
๋ ฅ: " << input << std::endl;
}
void off() { std::cout << "๐ฝ๏ธ ํ๋ก์ ํฐ ๊บผ์ง" << std::endl; }
};
class SoundSystem {
public:
void on() { std::cout << "๐ ์ฌ์ด๋ ์์คํ
์ผ์ง" << std::endl; }
void setVolume(int vol) {
std::cout << "๐ ๋ณผ๋ฅจ: " << vol << std::endl;
}
void setSurroundMode() {
std::cout << "๐ ์๋ผ์ด๋ ๋ชจ๋ ํ์ฑํ" << std::endl;
}
void off() { std::cout << "๐ ์ฌ์ด๋ ์์คํ
๊บผ์ง" << std::endl; }
};
class Lights {
public:
void dim(int level) {
std::cout << "๐ก ์กฐ๋ช
" << level << "% ๋ฐ๊ธฐ" << std::endl;
}
void on() { std::cout << "๐ก ์กฐ๋ช
์ผ์ง" << std::endl; }
};
class StreamingService {
public:
void connect() { std::cout << "๐ ์คํธ๋ฆฌ๋ฐ ์๋น์ค ์ฐ๊ฒฐ" << std::endl; }
void play(const std::string& movie) {
std::cout << "โถ๏ธ ์ฌ์: " << movie << std::endl;
}
void stop() { std::cout << "โน๏ธ ์ฌ์ ์ค์ง" << std::endl; }
};
// Facade - ๋ณต์กํ ์๋ธ์์คํ
์ ๋จ์ํ๊ฒ!
class HomeTheaterFacade {
private:
Projector projector;
SoundSystem sound;
Lights lights;
StreamingService streaming;
public:
// ์ํ ๋ณด๊ธฐ - ๋ณต์กํ ๊ณผ์ ์ ํ๋์ ๋ฉ์๋๋ก!
void watchMovie(const std::string& movie) {
std::cout << "\n๐ฌ === ์ํ ๋ชจ๋ ์์ ===" << std::endl;
lights.dim(20);
projector.on();
projector.setInput("HDMI");
sound.on();
sound.setSurroundMode();
sound.setVolume(70);
streaming.connect();
streaming.play(movie);
std::cout << "๐ฟ ์ฆ๊ฑฐ์ด ์ํ ๊ฐ์!" << std::endl;
}
// ์ํ ์ข
๋ฃ
void endMovie() {
std::cout << "\n๐ === ์ํ ๋ชจ๋ ์ข
๋ฃ ===" << std::endl;
streaming.stop();
sound.off();
projector.off();
lights.on();
}
};
int main() {
HomeTheaterFacade theater;
theater.watchMovie("์ธํฐ์คํ
๋ผ");
// ... ์ํ ๊ฐ์ ...
theater.endMovie();
return 0;
}
ํต์ฌ ๊ฐ๋
: ๋ค๋ฅธ ๊ฐ์ฒด์ ๋ํ ๋๋ฆฌ์(Proxy)๋ฅผ ์ ๊ณตํ์ฌ ์ ๊ทผ์ ์ ์ดํ๋ ํจํด.
Virtual Proxy(์ง์ฐ ๋ก๋ฉ), Protection Proxy(์ ๊ทผ ์ ์ด), Remote Proxy(์๊ฒฉ ๊ฐ์ฒด) ๋ฑ ๋ค์ํ ๋ณํ์ด ์์ด!
// ๐ก๏ธ Proxy ํจํด - ์ด๋ฏธ์ง ์ง์ฐ ๋ก๋ฉ (Virtual Proxy)
#include <iostream>
#include <string>
#include <memory>
// ๊ณตํต ์ธํฐํ์ด์ค
class Image {
public:
virtual ~Image() = default;
virtual void display() = 0;
virtual std::string getFilename() const = 0;
};
// ์ค์ ๊ฐ์ฒด - ์์ฑ ๋น์ฉ์ด ํผ
class RealImage : public Image {
private:
std::string filename;
void loadFromDisk() {
std::cout << "๐พ ๋์คํฌ์์ ๋ก๋ฉ: " << filename
<< " (์๊ฐ ์์...)" << std::endl;
}
public:
RealImage(const std::string& file) : filename(file) {
loadFromDisk(); // ์์ฑ ์ ๋ฐ๋ก ๋ก๋ฉ
}
void display() override {
std::cout << "๐ผ๏ธ ์ด๋ฏธ์ง ํ์: " << filename << std::endl;
}
std::string getFilename() const override { return filename; }
};
// ํ๋ก์ - ์ค์ ๊ฐ์ฒด ์์ฑ์ ์ง์ฐ์ํด
class ImageProxy : public Image {
private:
std::string filename;
mutable std::unique_ptr<RealImage> realImage; // ์ค์ ์ด๋ฏธ์ง (์ง์ฐ ์์ฑ)
public:
ImageProxy(const std::string& file) : filename(file) {
std::cout << "๐ ํ๋ก์ ์์ฑ: " << filename << " (์์ง ๋ก๋ฉ ์ ํจ)" << std::endl;
}
void display() override {
// ์ฒ์ display() ํธ์ถ ์์๋ง ์ค์ ์ด๋ฏธ์ง ์์ฑ
if (!realImage) {
std::cout << "โณ ํ์ํ ๋ ๋ก๋ฉ ์์..." << std::endl;
realImage = std::make_unique<RealImage>(filename);
}
realImage->display();
}
std::string getFilename() const override { return filename; }
};
int main() {
std::cout << "=== ์ด๋ฏธ์ง ๋ชฉ๋ก ์์ฑ ===" << std::endl;
// ํ๋ก์๋ ์ฆ์ ์์ฑ๋์ง๋ง ์ค์ ์ด๋ฏธ์ง๋ ์์ง ๋ก๋ฉ ์ ๋จ
ImageProxy img1("photo1.jpg");
ImageProxy img2("photo2.jpg");
ImageProxy img3("photo3.jpg");
std::cout << "\n=== ์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง๋ง ํ์ ===" << std::endl;
img1.display(); // ์ด๋ ์ค์ ๋ก๋ฉ ๋ฐ์
std::cout << "\n=== ์ฒซ ๋ฒ์งธ ์ด๋ฏธ์ง ๋ค์ ํ์ ===" << std::endl;
img1.display(); // ์ด๋ฏธ ๋ก๋ฉ๋จ, ๋ฐ๋ก ํ์
// img2, img3์ display() ์ ๋ถ๋ ์ผ๋ ๋ก๋ฉ ์ ๋จ = ๋ฉ๋ชจ๋ฆฌ ์ ์ฝ!
return 0;
}
ํ๋ ํจํด์ ๊ฐ์ฒด๋ค์ด ์ด๋ป๊ฒ ์ํธ์์ฉํ๊ณ ์ฑ
์์ ๋ถ๋ฐฐํ ์ง์ ๋ํ ํด๋ต์ด์ผ.
11๊ฐ์ง๋ก ๊ฐ์ฅ ๋ง์ ํจํด์ด ์๋ ์นดํ
๊ณ ๋ฆฌ! ๊ทธ ์ค ๊ฐ์ฅ ์ค์ํ๊ณ ์์ฃผ ์ฐ์ด๋ ๊ฒ๋ค ์์ฃผ๋ก ํํค์ณ๋ณผ๊ฒ ๐ฅ
ํต์ฌ ๊ฐ๋
: ๊ฐ์ฒด์ ์ํ ๋ณํ๋ฅผ ๊ด์ฐฐํ๋ ์ต์ ๋ฒ๋ค์๊ฒ ์๋์ผ๋ก ์๋ฆผ์ ๋ณด๋ด๋ ํจํด.
์ด๋ฒคํธ ๋ฆฌ์ค๋, MVC ํจํด์ Model-View ๊ด๊ณ, ์ฃผ์ ๊ฐ๊ฒฉ ์๋ฆผ ์์คํ
๋ฑ์์ ํต์ฌ์ ์ผ๋ก ์ฌ์ฉ๋ผ!
C++์์๋ std::function๊ณผ ๋๋ค๋ฅผ ํ์ฉํ๋ฉด ๋ ํ๋์ ์ผ๋ก ๊ตฌํ ๊ฐ๋ฅํจ!
// ๐๏ธ Observer ํจํด - ์ฃผ์ ๊ฐ๊ฒฉ ์๋ฆผ ์์คํ
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <functional>
// ์ต์ ๋ฒ ์ธํฐํ์ด์ค
class StockObserver {
public:
virtual ~StockObserver() = default;
virtual void onPriceChanged(const std::string& stock, double price) = 0;
};
// ์ฃผ์ (Subject) - ๊ด์ฐฐ ๋์
class StockMarket {
private:
std::vector<StockObserver*> observers;
std::string stockName;
double price;
public:
StockMarket(const std::string& name, double initialPrice)
: stockName(name), price(initialPrice) {}
void addObserver(StockObserver* observer) {
observers.push_back(observer);
std::cout << "๐ ์ต์ ๋ฒ ๋ฑ๋ก ์๋ฃ" << std::endl;
}
void removeObserver(StockObserver* observer) {
observers.erase(
std::remove(observers.begin(), observers.end(), observer),
observers.end()
);
}
void setPrice(double newPrice) {
price = newPrice;
std::cout << "\n๐ " << stockName << " ๊ฐ๊ฒฉ ๋ณ๋: "
<< newPrice << "์" << std::endl;
notifyObservers(); // ๋ชจ๋ ์ต์ ๋ฒ์๊ฒ ์๋ฆผ!
}
private:
void notifyObservers() {
for (auto* observer : observers) {
observer->onPriceChanged(stockName, price);
}
}
};
// ๊ตฌ์ฒด ์ต์ ๋ฒ๋ค
class InvestorAlert : public StockObserver {
private:
std::string name;
double targetPrice;
public:
InvestorAlert(const std::string& n, double target)
: name(n), targetPrice(target) {}
void onPriceChanged(const std::string& stock, double price) override {
if (price >= targetPrice) {
std::cout << "๐ [" << name << "] " << stock
<< " ๋ชฉํ๊ฐ ๋ฌ์ฑ! ํ์ฌ๊ฐ: " << price << "์" << std::endl;
} else {
std::cout << "๐ [" << name << "] " << stock
<< " ํ์ฌ๊ฐ: " << price << "์ (๋ชฉํ: "
<< targetPrice << "์)" << std::endl;
}
}
};
class StopLossAlert : public StockObserver {
private:
double stopLossPrice;
public:
StopLossAlert(double stopPrice) : stopLossPrice(stopPrice) {}
void onPriceChanged(const std::string& stock, double price) override {
if (price <= stopLossPrice) {
std::cout << "๐จ [์์ ์๋ฆผ] " << stock
<< " ์์ ๊ฐ ๋๋ฌ! ์ฆ์ ๋งค๋ ๊ถ๊ณ !" << std::endl;
}
}
};
int main() {
StockMarket samsung("์ผ์ฑ์ ์", 70000);
InvestorAlert investor1("๊นํฌ์", 75000);
InvestorAlert investor2("์ด์ฃผ์", 80000);
StopLossAlert stopLoss(65000);
samsung.addObserver(&investor1);
samsung.addObserver(&investor2);
samsung.addObserver(&stopLoss);
samsung.setPrice(72000);
samsung.setPrice(76000);
samsung.setPrice(64000); // ์์ ๊ฐ ๋๋ฌ!
return 0;
}
ํต์ฌ ๊ฐ๋
: ์๊ณ ๋ฆฌ์ฆ์ ์บก์ํํ๊ณ ๋ฐํ์์ ๊ต์ฒด ๊ฐ๋ฅํ๊ฒ ๋ง๋๋ ํจํด.
์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ, ๊ฒฐ์ ๋ฐฉ๋ฒ, ์์ถ ์๊ณ ๋ฆฌ์ฆ ๋ฑ "๋ฐฉ๋ฒ"์ด ์ฌ๋ฌ ๊ฐ์ง์ผ ๋ ๋ฑ์ด์ผ!
C++์์๋ std::function์ด๋ ๋๋ค๋ก๋ ๊ตฌํ ๊ฐ๋ฅํด์ ๋ ์ ์ฐํ๊ฒ ์ธ ์ ์์!
// ๐ฏ Strategy ํจํด - ์ ๋ ฌ ์ ๋ต ์์คํ
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <string>
// ์ ๋ต ์ธํฐํ์ด์ค
class SortStrategy {
public:
virtual ~SortStrategy() = default;
virtual void sort(std::vector<int>& data) = 0;
virtual std::string getName() const = 0;
};
// ๊ตฌ์ฒด ์ ๋ต๋ค
class BubbleSortStrategy : public SortStrategy {
public:
void sort(std::vector<int>& data) override {
int n = data.size();
for (int i = 0; i < n-1; i++) {
for (int j = 0; j < n-i-1; j++) {
if (data[j] > data[j+1]) {
std::swap(data[j], data[j+1]);
}
}
}
}
std::string getName() const override { return "๋ฒ๋ธ ์ ๋ ฌ"; }
};
class QuickSortStrategy : public SortStrategy {
public:
void sort(std::vector<int>& data) override {
std::sort(data.begin(), data.end()); // ์ค์ ๋ก๋ ํต์ํธ ๊ตฌํ
}
std::string getName() const override { return "ํต ์ ๋ ฌ"; }
};
class ReverseSortStrategy : public SortStrategy {
public:
void sort(std::vector<int>& data) override {
std::sort(data.begin(), data.end(), std::greater<int>());
}
std::string getName() const override { return "์ญ์ ์ ๋ ฌ"; }
};
// ์ปจํ
์คํธ - ์ ๋ต์ ์ฌ์ฉํ๋ ํด๋์ค
class DataSorter {
private:
std::unique_ptr<SortStrategy> strategy;
public:
DataSorter(std::unique_ptr<SortStrategy> s) : strategy(std::move(s)) {}
// ๋ฐํ์์ ์ ๋ต ๊ต์ฒด ๊ฐ๋ฅ!
void setStrategy(std::unique_ptr<SortStrategy> s) {
strategy = std::move(s);
}
void sortData(std::vector<int>& data) {
std::cout << "๐ " << strategy->getName() << " ์ฌ์ฉ ์ค..." << std::endl;
strategy->sort(data);
std::cout << "๊ฒฐ๊ณผ: ";
for (int val : data) std::cout << val << " ";
std::cout << std::endl;
}
};
int main() {
std::vector<int> data1 = {64, 34, 25, 12, 22, 11, 90};
std::vector<int> data2 = data1;
std::vector<int> data3 = data1;
DataSorter sorter(std::make_unique<BubbleSortStrategy>());
sorter.sortData(data1);
// ์ ๋ต ๊ต์ฒด!
sorter.setStrategy(std::make_unique<QuickSortStrategy>());
sorter.sortData(data2);
sorter.setStrategy(std::make_unique<ReverseSortStrategy>());
sorter.sortData(data3);
return 0;
}
ํต์ฌ ๊ฐ๋
: ์์ฒญ์ ๊ฐ์ฒด๋ก ์บก์ํํ์ฌ ๋งค๊ฐ๋ณ์ํ, ํ์, ๋ก๊น
, ์คํ์ทจ์(Undo)๋ฅผ ๊ฐ๋ฅํ๊ฒ ํ๋ ํจํด.
ํ
์คํธ ์๋ํฐ์ Ctrl+Z, ๊ฒ์์ ์ปค๋งจ๋ ์์คํ
, ํธ๋์ญ์
์ฒ๋ฆฌ์์ ํต์ฌ์ ์ผ๋ก ์ฌ์ฉ๋ผ!
// ๐ Command ํจํด - ํ
์คํธ ์๋ํฐ Undo/Redo
#include <iostream>
#include <string>
#include <stack>
#include <memory>
// ํ
์คํธ ์๋ํฐ (Receiver)
class TextEditor {
private:
std::string text;
public:
void insertText(const std::string& str, int pos) {
text.insert(pos, str);
std::cout << "โ๏ธ ์ฝ์
ํ: \"" << text << "\"" << std::endl;
}
void deleteText(int pos, int length) {
text.erase(pos, length);
std::cout << "๐๏ธ ์ญ์ ํ: \"" << text << "\"" << std::endl;
}
std::string getText() const { return text; }
};
// ์ปค๋งจ๋ ์ธํฐํ์ด์ค
class Command {
public:
virtual ~Command() = default;
virtual void execute() = 0;
virtual void undo() = 0;
};
// ๊ตฌ์ฒด ์ปค๋งจ๋๋ค
class InsertCommand : public Command {
private:
TextEditor& editor;
std::string text;
int position;
public:
InsertCommand(TextEditor& e, const std::string& t, int pos)
: editor(e), text(t), position(pos) {}
void execute() override {
editor.insertText(text, position);
}
void undo() override {
editor.deleteText(position, text.length());
std::cout << "โฉ๏ธ ์ฝ์
์ทจ์" << std::endl;
}
};
class DeleteCommand : public Command {
private:
TextEditor& editor;
std::string deletedText;
int position;
int length;
public:
DeleteCommand(TextEditor& e, int pos, int len)
: editor(e), position(pos), length(len) {
deletedText = e.getText().substr(pos, len);
}
void execute() override {
editor.deleteText(position, length);
}
void undo() override {
editor.insertText(deletedText, position);
std::cout << "โฉ๏ธ ์ญ์ ์ทจ์" << std::endl;
}
};
// ์ปค๋งจ๋ ๊ด๋ฆฌ์ (Invoker)
class CommandManager {
private:
std::stack<std::unique_ptr<Command>> history;
public:
void executeCommand(std::unique_ptr<Command> cmd) {
cmd->execute();
history.push(std::move(cmd));
}
void undo() {
if (!history.empty()) {
history.top()->undo();
history.pop();
} else {
std::cout << "โ ๏ธ ์ทจ์ํ ์์
์ด ์์ต๋๋ค." << std::endl;
}
}
};
int main() {
TextEditor editor;
CommandManager manager;
std::cout << "=== ํ
์คํธ ํธ์ง ===" << std::endl;
manager.executeCommand(std::make_unique<InsertCommand>(editor, "Hello", 0));
manager.executeCommand(std::make_unique<InsertCommand>(editor, " World", 5));
manager.executeCommand(std::make_unique<InsertCommand>(editor, "!", 11));
std::cout << "\n=== Undo 3๋ฒ ===" << std::endl;
manager.undo();
manager.undo();
manager.undo();
return 0;
}
ํต์ฌ ๊ฐ๋
: ์ปฌ๋ ์
์ ๋ด๋ถ ๊ตฌ์กฐ๋ฅผ ๋
ธ์ถํ์ง ์๊ณ ์์ฐจ์ ์ผ๋ก ์ ๊ทผํ๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๋ ํจํด.
C++ STL์ ์ดํฐ๋ ์ดํฐ๊ฐ ๋ฐ๋ก ์ด ํจํด์ ๊ตฌํ์ฒด์ผ! begin(), end(), ++ ์ฐ์ฐ์ ๋ค ์ด ํจํด์ ใ
ใ
// ๐ Iterator ํจํด - ์ปค์คํ
์ปฌ๋ ์
์ดํฐ๋ ์ดํฐ
#include <iostream>
#include <stdexcept>
// ์ดํฐ๋ ์ดํฐ ์ธํฐํ์ด์ค
template<typename T>
class Iterator {
public:
virtual ~Iterator() = default;
virtual bool hasNext() const = 0;
virtual T next() = 0;
};
// ์ปค์คํ
๋ฐฐ์ด ์ปฌ๋ ์
template<typename T>
class NumberCollection {
private:
T* data;
int size;
int capacity;
public:
NumberCollection(int cap) : size(0), capacity(cap) {
data = new T[capacity];
}
~NumberCollection() { delete[] data; }
void add(T value) {
if (size < capacity) data[size++] = value;
}
T get(int index) const { return data[index]; }
int getSize() const { return size; }
// ์ดํฐ๋ ์ดํฐ ํด๋์ค (๋ด๋ถ ํด๋์ค)
class NumberIterator : public Iterator<T> {
private:
const NumberCollection<T>& collection;
int current = 0;
public:
NumberIterator(const NumberCollection<T>& c) : collection(c) {}
bool hasNext() const override {
return current < collection.getSize();
}
T next() override {
if (!hasNext()) throw std::out_of_range("๋ ์ด์ ์์ ์์");
return collection.get(current++);
}
};
NumberIterator createIterator() const {
return NumberIterator(*this);
}
};
int main() {
NumberCollection<int> numbers(10);
numbers.add(10);
numbers.add(20);
numbers.add(30);
numbers.add(40);
numbers.add(50);
auto it = numbers.createIterator();
std::cout << "๐ ์ดํฐ๋ ์ดํฐ๋ก ์ํ: ";
while (it.hasNext()) {
std::cout << it.next() << " ";
}
std::cout << std::endl;
return 0;
}
ํต์ฌ ๊ฐ๋
: ๊ฐ์ฒด์ ๋ด๋ถ ์ํ์ ๋ฐ๋ผ ํ๋์ด ๋ฌ๋ผ์ง๋๋ก ํ๋ ํจํด. ๊ฑฐ๋ํ if-else๋ switch ๋ฌธ์ ์ ๊ฑฐํ ์ ์์ด!
์ํ๊ธฐ, ์ ํธ๋ฑ, ๊ฒ์ ์บ๋ฆญํฐ ์ํ ๊ด๋ฆฌ ๋ฑ์์ ์์ฃผ ์.
// ๐ญ State ํจํด - ์ํ๊ธฐ ์ํ ๊ด๋ฆฌ
#include <iostream>
#include <memory>
#include <string>
class VendingMachine; // ์ ๋ฐฉ ์ ์ธ
// ์ํ ์ธํฐํ์ด์ค
class State {
public:
virtual ~State() = default;
virtual void insertCoin(VendingMachine& machine) = 0;
virtual void selectProduct(VendingMachine& machine) = 0;
virtual void dispense(VendingMachine& machine) = 0;
virtual std::string getStateName() const = 0;
};
// ์ํ๊ธฐ (Context)
class VendingMachine {
private:
std::unique_ptr<State> currentState;
int stock;
public:
VendingMachine(int initialStock);
void setState(std::unique_ptr<State> state) {
currentState = std::move(state);
std::cout << "๐ ์ํ ๋ณ๊ฒฝ: " << currentState->getStateName() << std::endl;
}
void insertCoin() { currentState->insertCoin(*this); }
void selectProduct() { currentState->selectProduct(*this); }
void dispense() { currentState->dispense(*this); }
int getStock() const { return stock; }
void decreaseStock() { stock--; }
};
// ๊ตฌ์ฒด ์ํ๋ค
class IdleState : public State {
public:
void insertCoin(VendingMachine& machine) override;
void selectProduct(VendingMachine& machine) override {
std::cout << "โ ๏ธ ๋จผ์ ๋์ ์ ๋ฃ์ด์ฃผ์ธ์!" << std::endl;
}
void dispense(VendingMachine& machine) override {
std::cout << "โ ๏ธ ๋์ ์ ๋จผ์ ๋ฃ์ด์ฃผ์ธ์!" << std::endl;
}
std::string getStateName() const override { return "๋๊ธฐ ์ํ"; }
};
class HasCoinState : public State {
public:
void insertCoin(VendingMachine& machine) override {
std::cout << "โ ๏ธ ์ด๋ฏธ ๋์ ์ด ๋ค์ด์์ต๋๋ค!" << std::endl;
}
void selectProduct(VendingMachine& machine) override;
void dispense(VendingMachine& machine) override {
std::cout << "โ ๏ธ ๋จผ์ ์ํ์ ์ ํํด์ฃผ์ธ์!" << std::endl;
}
std::string getStateName() const override { return "๋์ ํฌ์
์ํ"; }
};
class DispensingState : public State {
public:
void insertCoin(VendingMachine& machine) override {
std::cout << "โ ๏ธ ์ํ ๋ฐฐ์ถ ์ค์
๋๋ค!" << std::endl;
}
void selectProduct(VendingMachine& machine) override {
std::cout << "โ ๏ธ ์ํ ๋ฐฐ์ถ ์ค์
๋๋ค!" << std::endl;
}
void dispense(VendingMachine& machine) override;
std::string getStateName() const override { return "๋ฐฐ์ถ ์ํ"; }
};
// ์ํ ์ ํ ๊ตฌํ
void IdleState::insertCoin(VendingMachine& machine) {
std::cout << "๐ฐ ๋์ ํฌ์
!" << std::endl;
machine.setState(std::make_unique<HasCoinState>());
}
void HasCoinState::selectProduct(VendingMachine& machine) {
std::cout << "๐ฏ ์ํ ์ ํ!" << std::endl;
machine.setState(std::make_unique<DispensingState>());
}
void DispensingState::dispense(VendingMachine& machine) {
if (machine.getStock() > 0) {
machine.decreaseStock();
std::cout << "๐ฅค ์ํ ๋ฐฐ์ถ ์๋ฃ!" << std::endl;
machine.setState(std::make_unique<IdleState>());
} else {
std::cout << "โ ์ฌ๊ณ ์์!" << std::endl;
machine.setState(std::make_unique<IdleState>());
}
}
VendingMachine::VendingMachine(int initialStock) : stock(initialStock) {
currentState = std::make_unique<IdleState>();
std::cout << "๐ช ์ํ๊ธฐ ์ด๊ธฐํ (์ฌ๊ณ : " << stock << "๊ฐ)" << std::endl;
}
int main() {
VendingMachine machine(3);
std::cout << "\n=== ์ ์ ๊ตฌ๋งค ===" << std::endl;
machine.insertCoin();
machine.selectProduct();
machine.dispense();
std::cout << "\n=== ์๋ชป๋ ์์ ===" << std::endl;
machine.selectProduct(); // ๋์ ์์ด ์ ํ ์๋
machine.insertCoin();
machine.insertCoin(); // ์ค๋ณต ํฌ์
์๋
machine.selectProduct();
machine.dispense();
return 0;
}
ํต์ฌ ๊ฐ๋
: ์๊ณ ๋ฆฌ์ฆ์ ๊ณจ๊ฒฉ์ ์ ์ํ๊ณ , ์ผ๋ถ ๋จ๊ณ๋ฅผ ์๋ธํด๋์ค์์ ๊ตฌํํ๋๋ก ํ๋ ํจํด.
"ํ๋ฆฌ์ฐ๋ ์์น - Don't call us, we'll call you"๋ฅผ ๊ตฌํํ ํจํด์ด์ผ!
// ๐ Template Method ํจํด - ์๋ฃ ์ ์กฐ ํ๋ก์ธ์ค
#include <iostream>
#include <string>
class BeverageMaker {
public:
// ํ
ํ๋ฆฟ ๋ฉ์๋ - ์๊ณ ๋ฆฌ์ฆ ๊ณจ๊ฒฉ ์ ์ (final๋ก ์ค๋ฒ๋ผ์ด๋ ๋ฐฉ์ง)
void makeBeverage() {
boilWater();
brew(); // ์๋ธํด๋์ค์์ ๊ตฌํ
pourInCup();
if (customerWantsCondiments()) { // ํ
๋ฉ์๋
addCondiments(); // ์๋ธํด๋์ค์์ ๊ตฌํ
}
std::cout << "โ
" << getBeverageName() << " ์์ฑ!" << std::endl;
}
virtual ~BeverageMaker() = default;
protected:
void boilWater() {
std::cout << "๐ง ๋ฌผ ๋์ด๋ ์ค..." << std::endl;
}
void pourInCup() {
std::cout << "โ ์ปต์ ๋ฐ๋ฅด๋ ์ค..." << std::endl;
}
// ์๋ธํด๋์ค์์ ๋ฐ๋์ ๊ตฌํํด์ผ ํ๋ ์ถ์ ๋ฉ์๋
virtual void brew() = 0;
virtual void addCondiments() = 0;
virtual std::string getBeverageName() const = 0;
// ํ
๋ฉ์๋ - ์ ํ์ ์ผ๋ก ์ค๋ฒ๋ผ์ด๋ ๊ฐ๋ฅ
virtual bool customerWantsCondiments() const { return true; }
};
class CoffeeMaker : public BeverageMaker {
protected:
void brew() override {
std::cout << "โ ์ปคํผ ์๋ ์ฐ๋ ค๋ด๋ ์ค..." << std::endl;
}
void addCondiments() override {
std::cout << "๐ฅ ์คํ๊ณผ ์ฐ์ ์ถ๊ฐ!" << std::endl;
}
std::string getBeverageName() const override { return "์ปคํผ"; }
};
class TeaMaker : public BeverageMaker {
protected:
void brew() override {
std::cout << "๐ต ์ฐจ ์ฐ๋ ค๋ด๋ ์ค..." << std::endl;
}
void addCondiments() override {
std::cout << "๐ ๋ ๋ชฌ ์ถ๊ฐ!" << std::endl;
}
std::string getBeverageName() const override { return "์ฐจ"; }
// ํ
๋ฉ์๋ ์ค๋ฒ๋ผ์ด๋ - ์ด ์ฐจ๋ ์ฒจ๊ฐ๋ฌผ ์์ด!
bool customerWantsCondiments() const override { return false; }
};
int main() {
std::cout << "=== ์ปคํผ ๋ง๋ค๊ธฐ ===" << std::endl;
CoffeeMaker coffee;
coffee.makeBeverage();
std::cout << "\n=== ์ฐจ ๋ง๋ค๊ธฐ ===" << std::endl;
TeaMaker tea;
tea.makeBeverage();
return 0;
}
| ํจํด๋ช | ๋ถ๋ฅ | ํต์ฌ ๋ชฉ์ | ์ฃผ์ ์ฌ์ฉ์ฒ |
|---|---|---|---|
| Singleton | ์์ฑ | ๋จ์ผ ์ธ์คํด์ค ๋ณด์ฅ | ๋ก๊ฑฐ, DB ์ฐ๊ฒฐ, ์ค์ ๊ด๋ฆฌ |
| Factory Method | ์์ฑ | ๊ฐ์ฒด ์์ฑ์ ์๋ธํด๋์ค์ ์์ | ํ๋ ์์ํฌ, ํ๋ฌ๊ทธ์ธ ์์คํ |
| Abstract Factory | ์์ฑ | ๊ด๋ จ ๊ฐ์ฒด๊ตฐ ์์ฑ | UI ํ ๋ง, ํฌ๋ก์ค ํ๋ซํผ |
| Builder | ์์ฑ | ๋ณต์กํ ๊ฐ์ฒด ๋จ๊ณ๋ณ ์์ฑ | ์ฟผ๋ฆฌ ๋น๋, ์ค์ ๊ฐ์ฒด |
| Prototype | ์์ฑ | ๊ธฐ์กด ๊ฐ์ฒด ๋ณต์ | ๊ฒ์ ์ค๋ธ์ ํธ, ์บ์ฑ |
| Adapter | ๊ตฌ์กฐ | ์ธํฐํ์ด์ค ๋ณํ | ๋ ๊ฑฐ์ ์ฝ๋ ์ฐ๋ |
| Decorator | ๊ตฌ์กฐ | ๋์ ๊ธฐ๋ฅ ์ถ๊ฐ | I/O ์คํธ๋ฆผ, ๋ฏธ๋ค์จ์ด |
| Facade | ๊ตฌ์กฐ | ๋ณต์ก์ฑ ์จ๊ธฐ๊ธฐ | ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ํผ |
| Proxy | ๊ตฌ์กฐ | ์ ๊ทผ ์ ์ด/์ง์ฐ ๋ก๋ฉ | ์บ์ฑ, ๋ณด์, ์๊ฒฉ ๊ฐ์ฒด |
| Observer | ํ๋ | 1:N ์ด๋ฒคํธ ์๋ฆผ | ์ด๋ฒคํธ ์์คํ , MVC |
| Strategy | ํ๋ | ์๊ณ ๋ฆฌ์ฆ ๊ต์ฒด | ์ ๋ ฌ, ๊ฒฐ์ , ์์ถ |
| Command | ํ๋ | ์์ฒญ ์บก์ํ | Undo/Redo, ํธ๋์ญ์ |
| State | ํ๋ | ์ํ๋ณ ํ๋ ๋ณ๊ฒฝ | ์ํ ๊ธฐ๊ณ, ๊ฒ์ AI |
| Template Method | ํ๋ | ์๊ณ ๋ฆฌ์ฆ ๊ณจ๊ฒฉ ์ ์ | ํ๋ ์์ํฌ, ํ ๋ฉ์๋ |
| Iterator | ํ๋ | ์ปฌ๋ ์ ์ํ | STL ์ดํฐ๋ ์ดํฐ |
C++11 ์ดํ๋ก ์ธ์ด ์์ฒด๊ฐ ๋ง์ด ๋ฐ์ ํ๋ฉด์ ๋์์ธ ํจํด ๊ตฌํ ๋ฐฉ์๋ ๋ฌ๋ผ์ก์ด!
std::function, ๋๋ค, std::unique_ptr, std::shared_ptr, ๊ฐ๋ณ ํ
ํ๋ฆฟ ๋ฑ์ ํ์ฉํ๋ฉด
๋ ๊ฐ๊ฒฐํ๊ณ ์์ ํ ํจํด ๊ตฌํ์ด ๊ฐ๋ฅํด์ง ๐
ํ๋ C++์์ Strategy ํจํด์ ๋๋ค๋ก ๊ตฌํํ๋ฉด ์ด๋ ๊ฒ ํจ์ฌ ๊ฐ๊ฒฐํด์ ธ!
// โก ํ๋ C++ - ๋๋ค๋ก Strategy ํจํด ๊ตฌํ
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
class ModernSorter {
private:
// std::function์ผ๋ก ์ ๋ต ์ ์ฅ
std::function<bool(int, int)> compareStrategy;
public:
// ๋๋ค๋ ํจ์ ํฌ์ธํฐ๋ฅผ ์ ๋ต์ผ๋ก ๋ฐ์
ModernSorter(std::function<bool(int, int)> strategy)
: compareStrategy(strategy) {}
void sort(std::vector<int>& data) {
std::sort(data.begin(), data.end(), compareStrategy);
}
};
// CRTP (Curiously Recurring Template Pattern) - ์ ์ ๋คํ์ฑ
template<typename Derived>
class CRTPBase {
public:
void interface() {
static_cast<Derived*>(this)->implementation();
}
};
class CRTPDerived : public CRTPBase<CRTPDerived> {
public:
void implementation() {
std::cout << "๐ฏ CRTP: ๊ฐ์ํจ์ ์์ด ๋คํ์ฑ ๊ตฌํ!" << std::endl;
}
};
int main() {
std::vector<int> data = {5, 2, 8, 1, 9, 3};
// ๋๋ค๋ก ์ค๋ฆ์ฐจ์ ์ ๋ต
ModernSorter ascSorter([](int a, int b) { return a < b; });
ascSorter.sort(data);
std::cout << "์ค๋ฆ์ฐจ์: ";
for (int v : data) std::cout << v << " ";
std::cout << std::endl;
// ๋๋ค๋ก ๋ด๋ฆผ์ฐจ์ ์ ๋ต
ModernSorter descSorter([](int a, int b) { return a > b; });
descSorter.sort(data);
std::cout << "๋ด๋ฆผ์ฐจ์: ";
for (int v : data) std::cout << v << " ";
std::cout << std::endl;
// CRTP ์ฌ์ฉ
CRTPDerived obj;
obj.interface();
return 0;
}
CRTP๋ GoF ํจํด์ ์๋์ง๋ง C++์์ ๋งค์ฐ ์ค์ํ ์ด๋์์ด์ผ. ๊ฐ์ํจ์ ์์ด ์ปดํ์ผ ํ์์ ๋คํ์ฑ์ ๊ตฌํํด์ ๋ฐํ์ ์ค๋ฒํค๋๊ฐ ์์ด! ์ฑ๋ฅ์ด ์ค์ํ ๊ฒ์ ์์ง์ด๋ ์๋ฒ ๋๋ ์์คํ ์์ ์์ฃผ ์.
ํจํด์ ์์๋ค๊ณ ๋ค๊ฐ ์๋์ผ! ์ธ์ ์ด๋ค ํจํด์ ์จ์ผ ํ๋์ง๊ฐ ์ง์ง ์ค๋ ฅ์ด๊ฑฐ๋ ใ
ใ
ํ์
์์ ์์ฃผ ๋ง์ฃผ์น๋ ์ํฉ๋ณ๋ก ์ด๋ค ํจํด์ ์ ํํด์ผ ํ๋์ง ์ ๋ฆฌํด๋ดค์ด!
๊ฐ์ฒด ์์ฑ ๊ด๋ จ ๋ฌธ์ ?
โ ์ธ์คํด์ค ํ๋๋ง ํ์ โ Singleton
โ ์ด๋ค ํด๋์ค ๋ง๋ค์ง ๋ชจ๋ฆ โ Factory Method
โ ๊ด๋ จ ๊ฐ์ฒด๋ค ๋ฌถ์ด์ ์์ฑ โ Abstract Factory
โ ์์ฑ์ ํ๋ผ๋ฏธํฐ ๋๋ฌด ๋ง์ โ Builder
โ ๋น์ทํ ๊ฐ์ฒด ๋ง์ด ํ์ โ Prototype
๊ตฌ์กฐ/์กฐํฉ ๊ด๋ จ ๋ฌธ์ ?
โ ์ธํฐํ์ด์ค ์ ๋ง์ โ Adapter
โ ๊ธฐ๋ฅ ๋์ ์ผ๋ก ์ถ๊ฐ โ Decorator
โ ๋ณต์กํ ์์คํ ๋จ์ํ โ Facade
โ ์ ๊ทผ ์ ์ด/์ง์ฐ ๋ก๋ฉ โ Proxy
ํ๋/์๊ณ ๋ฆฌ์ฆ ๊ด๋ จ ๋ฌธ์ ?
โ ์ํ ๋ณํ ์๋ฆผ ํ์ โ Observer
โ ์๊ณ ๋ฆฌ์ฆ ๊ต์ฒด ํ์ โ Strategy
โ Undo/Redo ํ์ โ Command
โ ์ํ์ ๋ฐ๋ผ ํ๋ ๋ค๋ฆ โ State
โ ์๊ณ ๋ฆฌ์ฆ ๊ณจ๊ฒฉ ๊ณ ์ โ Template Method
๋์์ธ ํจํด์ ๋๊ตฌ์ผ, ๋ชฉ์ ์ด ์๋์ผ! ๋ค์ ์ํฉ์์๋ ํจํด ์ ์ฉ์ ์ฌ๊ณ ํด๋ด:
โข Over-engineering: ๊ฐ๋จํ ๋ฌธ์ ์ ๋ณต์กํ ํจํด ์ ์ฉ โ ์ฝ๋๋ง ๋ณต์กํด์ง
โข Pattern Fever: ๋ชจ๋ ๊ณณ์ ํจํด ์ ์ฉํ๋ ค๋ ์์ฌ โ ์ ์ง๋ณด์ ์ง์ฅ
โข Premature Abstraction: ์์ง ํ์ํ์ง ์์ ์ ์ฐ์ฑ์ ์ํด ํจํด ์ ์ฉ
"Make it work, make it right, make it fast" - ๋จผ์ ๋์ํ๊ฒ ๋ง๋ค๊ณ , ๊ทธ ๋ค์์ ํจํด์ ๊ณ ๋ คํด!
1๋จ๊ณ (์ ๋ฌธ): Singleton, Factory Method, Observer, Strategy ๋จผ์ ์ตํ๊ธฐ
2๋จ๊ณ (์ค๊ธ): Decorator, Command, Builder, Facade ํ์ต
3๋จ๊ณ (๊ณ ๊ธ): Abstract Factory, Composite, Proxy, State, Template Method
4๋จ๊ณ (์ฌํ): ๋๋จธ์ง ํจํด + ํจํด ์กฐํฉ + ํ๋ C++ ์ด๋์ ์ ์ฉ
๐ก ์ถ์ฒ ํ์ต๋ฒ: ํจํด ํ๋๋ฅผ ๋ฐฐ์ธ ๋๋ง๋ค ์ค์ ํ๋ก์ ํธ์ ์ ์ฉํด๋ณด๋ ๊ฒ ์ต๊ณ ์ผ!
์ฌ๋ฅ๋ท์์ C++ ๊ด๋ จ ๋ฉํ ๋ง์ ์ฐพ์๋ณด๋ ๊ฒ๋ ์ข์ ๋ฐฉ๋ฒ์ด์ผ - ์ค๋ฌด ๊ฒฝํ์์๊ฒ ์ง์ ๋ฐฐ์ฐ๋ฉด ์ดํด๊ฐ ํจ์ฌ ๋น ๋ฅด๊ฑฐ๋ ! ๐
์ฌ๊ธฐ๊น์ง GoF 23๊ฐ์ง ํจํด ์ค ํต์ฌ์ ์ธ ๊ฒ๋ค์ C++๋ก ๊ตฌํํด๋ดค์ด!
๋ง์ง๋ง์ผ๋ก ๋์์ธ ํจํด์ ๊ณต๋ถํ๋ฉด์ ๊ผญ ๊ธฐ์ตํด์ผ ํ ๊ฒ๋ค ์ ๋ฆฌํด์ค๊ฒ ๐
1. ํจํด์ ์ธ์ด๊ฐ ์๋๋ผ ๊ฐ๋ ์ด์ผ
C++, Java, Python ์ด๋์๋ ๊ฐ์ ํจํด์ ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ๊ตฌํํ ์ ์์ด. ์ธ์ด์ ์ข ์๋์ง ๋ง๊ณ ๊ฐ๋ ์ ์ดํดํด!
2. ๋ฌธ์ ๊ฐ ๋จผ์ , ํจํด์ ๋์ค์ด์ผ
"์ด ํจํด ์จ์ผ์ง!" ๊ฐ ์๋๋ผ "์ด ๋ฌธ์ ๋ฅผ ์ด๋ป๊ฒ ํด๊ฒฐํ ๊น?" ์์ ์์ํด์ผ ํด. ํจํด์ ํด๊ฒฐ์ฑ ์ด์ง ๋ชฉ์ ์ด ์๋!
3. ํจํด๋ค์ ์๋ก ์กฐํฉ๋ผ
์ค์ ํ๋ก์ ํธ์์๋ ์ฌ๋ฌ ํจํด์ด ํจ๊ป ์ฌ์ฉ๋ผ. Factory + Singleton, Observer + Command ๊ฐ์ ์กฐํฉ์ด ํํด!
4. ๋ฆฌํฉํ ๋ง์ ํตํด ํจํด์ด ๋ํ๋์ผ ํด
์ฒ์๋ถํฐ ํจํด์ ๊ฐ์ ๋ก ์ ์ฉํ์ง ๋ง๊ณ , ์ฝ๋๊ฐ ๋ณต์กํด์ง ๋ ์์ฐ์ค๋ฝ๊ฒ ํจํด์ผ๋ก ๋ฆฌํฉํ ๋งํ๋ ๊ฒ ๋ง์!
5. ํ๋ C++ ๊ธฐ๋ฅ์ ์ ๊ทน ํ์ฉํด
์ค๋งํธ ํฌ์ธํฐ, ๋๋ค, ์ด๋ ์๋ฏธ๋ก ์ ํ์ฉํ๋ฉด ๋ ์์ ํ๊ณ ๊ฐ๊ฒฐํ ํจํด ๊ตฌํ์ด ๊ฐ๋ฅํด!
โข ๐ Design Patterns: Elements of Reusable Object-Oriented Software - GoF ์์ (๋ฐ์ด๋ธ!)
โข ๐ Head First Design Patterns - ์ ๋ฌธ์์๊ฒ ์ต๊ณ ์ ์ฑ
โข ๐ Modern C++ Design - Andrei Alexandrescu (๊ณ ๊ธ์์ฉ)
โข ๐ refactoring.guru - ํจํด๋ณ ์๊ฐ์ ์ค๋ช ๊ณผ ๋ค์ํ ์ธ์ด ์์
โข ๐ป ์ค์ ์คํ์์ค ํ๋ก์ ํธ ์ฝ๋ ๋ถ์ (Qt, Boost, LLVM ๋ฑ)
๊ทธ๋ฆฌ๊ณ ์ฌ๋ฅ๋ท์์ C++ ์ ๋ฌธ๊ฐ์๊ฒ 1:1 ์ฝ๋ ๋ฆฌ๋ทฐ๋ฅผ ๋ฐ์๋ณด๋ ๊ฒ๋ ์์ฒญ ๋์์ด ๋ผ! ์ด๋ก ๋ง์ผ๋ก๋ ํ๊ณ๊ฐ ์๊ฑฐ๋ ๐
๋์์ธ ํจํด์ ์ฒ์์ ์ด๋ ต๊ฒ ๋๊ปด์ง์ง๋ง, ํ๋์ฉ ์ค์ ์ฝ๋์ ์ ์ฉํด๋ณด๋ฉด์ ์ตํ๋ค ๋ณด๋ฉด
์ด๋ ์๊ฐ "์, ์ด ์ํฉ์์๋ ์ด ํจํด์ด๋ค!" ํ๊ณ ์์ฐ์ค๋ฝ๊ฒ ๋ ์ค๋ฅด๊ฒ ๋ผ.
๊ทธ ์๊ฐ์ด ์ค๋ฉด ์ง์ง C++ ๊ฐ๋ฐ์๋ก ํ ๋จ๊ณ ์
๊ทธ๋ ์ด๋๋ ๊ฑฐ์ผ! ๐
๊พธ์คํ ์ฝ๋ฉํ๊ณ , ๊พธ์คํ ๋ฆฌํฉํ ๋งํ๊ณ , ๊พธ์คํ ์ฑ์ฅํ์! ํ์ดํ
! ๐ช
๊ด๋ จ ํค์๋
๋๊ธ ์์ฑ
์ด ๊ธ์ ๋ํ ์ฌ๋ฌ๋ถ์ ์๊ฐ์ ๋ค๋ ค์ฃผ์ธ์
๋ก๊ทธ์ธ์ด ํ์ํฉ๋๋ค
๋๊ธ์ ์์ฑํ๋ ค๋ฉด ๋จผ์ ๋ก๊ทธ์ธํด์ฃผ์ธ์.
๋๊ธ 0
์ง์์ธ์ ์ฒ - ์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
- ์ ์๊ถ ๋ฐ ์์ ๊ถ: ๋ณธ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ๋ ์ AI ๊ธฐ์ ๋ก ์์ฑ๋์์ผ๋ฉฐ, ๋ํ๋ฏผ๊ตญ ์ ์๊ถ๋ฒ ๋ฐ ๊ตญ์ ์ ์๊ถ ํ์ฝ์ ์ํด ๋ณดํธ๋ฉ๋๋ค.
- AI ์์ฑ ์ปจํ ์ธ ์ ๋ฒ์ ์ง์: ๋ณธ AI ์์ฑ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ์ง์ ์ฐฝ์๋ฌผ๋ก ์ธ์ ๋๋ฉฐ, ๊ด๋ จ ๋ฒ๊ท์ ๋ฐ๋ผ ์ ์๊ถ ๋ณดํธ๋ฅผ ๋ฐ์ต๋๋ค.
- ์ฌ์ฉ ์ ํ: ์ฌ๋ฅ๋ท์ ๋ช ์์ ์๋ฉด ๋์ ์์ด ๋ณธ ์ปจํ ์ธ ๋ฅผ ๋ณต์ , ์์ , ๋ฐฐํฌ, ๋๋ ์์ ์ ์ผ๋ก ํ์ฉํ๋ ํ์๋ ์๊ฒฉํ ๊ธ์ง๋ฉ๋๋ค.
- ๋ฐ์ดํฐ ์์ง ๊ธ์ง: ๋ณธ ์ปจํ ์ธ ์ ๋ํ ๋ฌด๋จ ์คํฌ๋ํ, ํฌ๋กค๋ง, ๋ฐ ์๋ํ๋ ๋ฐ์ดํฐ ์์ง์ ๋ฒ์ ์ ์ฌ์ ๋์์ด ๋ฉ๋๋ค.
- AI ํ์ต ์ ํ: ์ฌ๋ฅ๋ท์ AI ์์ฑ ์ปจํ ์ธ ๋ฅผ ํ AI ๋ชจ๋ธ ํ์ต์ ๋ฌด๋จ ์ฌ์ฉํ๋ ํ์๋ ๊ธ์ง๋๋ฉฐ, ์ด๋ ์ง์ ์ฌ์ฐ๊ถ ์นจํด๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.
์์ง ๋๊ธ์ด ์์ต๋๋ค.