Ver3.0 ๐ฏ C++ ๊ฐ์ฒด์งํฅ๊ณผ ๋คํ์ฑ, ๊ฐ์ํจ์๋ถํฐ ์ค๊ณ ํจํด๊น์ง!

๐ฏ C++ ๊ฐ์ฒด์งํฅ๊ณผ ๋คํ์ฑ, ๊ฐ์ํจ์๋ถํฐ ์ค๊ณ ํจํด๊น์ง!
์ด ๊ธ์์๋ ๊ฐ์ํจ์, ์ถ์ํด๋์ค, ๊ทธ๋ฆฌ๊ณ ์ค๋ฌด์์ ์ ๋ง ๋ง์ด ์ฐ์ด๋ ๋์์ธ ํจํด๊น์ง ์ ๋ถ ๋ค๋ฃฐ ๊ฑฐ์ผ. ํ๋ก๊ทธ๋๋ฐ ๊ณต๋ถํ๋ฉด์ ๋ง๋งํ๋ ๋ถ๋ถ๋ค, ์ด์ ์์ํ๊ฒ ํ์ด๋ณด์! ๐ช
๐ช ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ํต์ฌ, ๋คํ์ฑ์ด๋?
์๋ฅผ ๋ค์ด๋ณผ๊ฒ. ๋๊ฐ ๋๋ฌผ์ ๊ด๋ฆฌ ํ๋ก๊ทธ๋จ์ ๋ง๋ ๋ค๊ณ ์๊ฐํด๋ด. ๐ฆ๐ถ๐ฑ
class Animal {
public:
void makeSound() {
cout << "๋๋ฌผ ์๋ฆฌ!" << endl;
}
};
class Dog : public Animal {
public:
void makeSound() {
cout << "๋ฉ๋ฉ!" << endl;
}
};
class Cat : public Animal {
public:
void makeSound() {
cout << "์ผ์น!" << endl;
}
};
์ด๋ ๊ฒ ์ฝ๋๋ฅผ ์งฐ๋ค๋ฉด, ๊ฐ ๋๋ฌผ๋ง๋ค ๋ค๋ฅธ ์๋ฆฌ๋ฅผ ๋ผ ์ ์์ด. ๊ทผ๋ฐ ๋ฌธ์ ๊ฐ ์์ด! ๐ฑAnimal* animal = new Dog();
animal->makeSound(); // ๊ฒฐ๊ณผ: "๋๋ฌผ ์๋ฆฌ!" (์ด? ๋ฉ๋ฉ์ด ์๋๋ค?)
์ ์ด๋ฐ ์ผ์ด ๋ฒ์ด์ง๊น? ๋ฐ๋ก ์ ์ ๋ฐ์ธ๋ฉ(Static Binding) ๋๋ฌธ์ด์ผ. ์ปดํ์ผ๋ฌ๊ฐ ํฌ์ธํฐ์ ํ์
(Animal*)๋ง ๋ณด๊ณ ์ด๋ค ํจ์๋ฅผ ํธ์ถํ ์ง ๊ฒฐ์ ํด๋ฒ๋ฆฌ๊ฑฐ๋ .์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๊ฒ ๋ฐ๋ก ๊ฐ์ํจ์(Virtual Function)์ผ! ๐ฏ
๐ฎ ๊ฐ์ํจ์(Virtual Function)์ ๋ง๋ฒ
class Animal {
public:
virtual void makeSound() { // virtual ํค์๋ ์ถ๊ฐ!
cout << "๋๋ฌผ ์๋ฆฌ!" << endl;
}
virtual ~Animal() {} // ๊ฐ์ ์๋ฉธ์๋ ์ค์ํด!
};
class Dog : public Animal {
public:
void makeSound() override { // override ํค์๋๋ก ๋ช
ํํ๊ฒ!
cout << "๋ฉ๋ฉ!" << endl;
}
};
class Cat : public Animal {
public:
void makeSound() override {
cout << "์ผ์น!" << endl;
}
};
์ด์ ๋ค์ ํ
์คํธํด๋ณด๋ฉด?Animal* animal1 = new Dog();
Animal* animal2 = new Cat();
animal1->makeSound(); // ๊ฒฐ๊ณผ: "๋ฉ๋ฉ!" ๐
animal2->makeSound(); // ๊ฒฐ๊ณผ: "์ผ์น!" ๐
delete animal1;
delete animal2;
์๋ฒฝํ๊ฒ ์๋ํด! ์ด๊ฒ ๋ฐ๋ก ๋์ ๋ฐ์ธ๋ฉ(Dynamic Binding)์ด์ผ. ์คํ ์์ ์ ์ค์ ๊ฐ์ฒด์ ํ์
์ ํ์ธํด์ ์ ์ ํ ํจ์๋ฅผ ํธ์ถํ๋ ๊ฑฐ์ง. ๐ฏvirtual ํค์๋๋ฅผ ๋ถ์ด๋ฉด ์ปดํ์ผ๋ฌ๊ฐ ๋ด๋ถ์ ์ผ๋ก vtable(๊ฐ์ ํจ์ ํ ์ด๋ธ)์ด๋ผ๋ ๊ฑธ ๋ง๋ค์ด. ์ด ํ ์ด๋ธ์๋ ๊ฐ ํด๋์ค์ ๊ฐ์ํจ์ ์ฃผ์๊ฐ ์ ์ฅ๋์ด ์๊ณ , ๋ฐํ์์ ์ด ํ ์ด๋ธ์ ์ฐธ์กฐํด์ ์ฌ๋ฐ๋ฅธ ํจ์๋ฅผ ํธ์ถํ๋ ๊ฑฐ์ผ! ๐๏ธ
๐ ๊ฐ์ํจ์ ์ฌ์ฉ ์ ์ฃผ์์ฌํญ
์, ๊ฐ์ํจ์๋ฅผ ์ธ ๋ ๊ผญ ์์์ผ ํ ๊ฒ๋ค์ด ์์ด:1๏ธโฃ ๊ฐ์ ์๋ฉธ์๋ ํ์!
class Base {
public:
virtual ~Base() { // ์ด๊ฑฐ ์์ผ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์ ๋ฐ์!
cout << "Base ์๋ฉธ์" << endl;
}
};
class Derived : public Base {
private:
int* data;
public:
Derived() { data = new int[100]; }
~Derived() {
delete[] data; // ์ด๊ฒ ํธ์ถ ์ ๋๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์!
cout << "Derived ์๋ฉธ์" << endl;
}
};
๋ง์ฝ Base์ ์๋ฉธ์๊ฐ ๊ฐ์ํจ์๊ฐ ์๋๋ฉด, Base* ptr = new Derived(); ํ์ delete ptr;์ ํด๋ Derived์ ์๋ฉธ์๊ฐ ํธ์ถ ์ ๋ผ! ๐ฑ ๋ฉ๋ชจ๋ฆฌ ๋์์ ์ฃผ๋ฒ์ด์ง.2๏ธโฃ override ํค์๋ ํ์ฉํ๊ธฐ
C++11๋ถํฐ override ํค์๋๊ฐ ์ถ๊ฐ๋์ด. ์ด๊ฑฐ ์ง์ง ์ ์ฉํด!
class Animal {
public:
virtual void makeSound() const { }
};
class Dog : public Animal {
public:
// ์ค์๋ก const๋ฅผ ๋นผ๋จน์๋ค๋ฉด?
void makeSound() override { // ์ปดํ์ผ ์๋ฌ ๋ฐ์! ๐
cout << "๋ฉ๋ฉ!" << endl;
}
};
override๋ฅผ ๋ถ์ด๋ฉด ์ปดํ์ผ๋ฌ๊ฐ "์ด ํจ์๊ฐ ์ ๋ง ๋ถ๋ชจ ํด๋์ค์ ๊ฐ์ํจ์๋ฅผ ์ค๋ฒ๋ผ์ด๋ํ๋์ง" ์ฒดํฌํด์ค. ์ค์๋ฅผ ๋ฏธ๋ฆฌ ์ก์์ฃผ๋ ๊ฑฐ์ง! ๐ก๏ธ3๏ธโฃ final ํค์๋๋ก ์ค๋ฒ๋ผ์ด๋ ๋ฐฉ์ง
class Animal {
public:
virtual void makeSound() { }
};
class Dog : public Animal {
public:
void makeSound() final { // ๋ ์ด์ ์ค๋ฒ๋ผ์ด๋ ๋ถ๊ฐ!
cout << "๋ฉ๋ฉ!" << endl;
}
};
class Puppy : public Dog {
public:
void makeSound() { } // ์ปดํ์ผ ์๋ฌ!
};
ํน์ ํจ์๋ฅผ ๋ ์ด์ ์ค๋ฒ๋ผ์ด๋ํ์ง ๋ชปํ๊ฒ ๋ง๊ณ ์ถ์ ๋ final์ ์ฌ์ฉํด! ๐ซ
๐๏ธ ์์ ๊ฐ์ํจ์์ ์ถ์ํด๋์ค
class Shape {
public:
// = 0์ ๋ถ์ด๋ฉด ์์ ๊ฐ์ํจ์!
virtual double getArea() const = 0;
virtual void draw() const = 0;
virtual ~Shape() {}
};
์์ ๊ฐ์ํจ์๋ฅผ ํ๋๋ผ๋ ๊ฐ์ง ํด๋์ค๋ ์ถ์ํด๋์ค(Abstract Class)๊ฐ ๋ผ. ์ถ์ํด๋์ค๋ ์ง์ ๊ฐ์ฒด๋ฅผ ๋ง๋ค ์ ์์ด! ๐ซShape shape; // ์ปดํ์ผ ์๋ฌ! ์ถ์ํด๋์ค๋ ์ธ์คํด์คํ ๋ถ๊ฐ
Shape* ptr = new Shape(); // ์ด๊ฒ๋ ์๋ฌ!
๋์ ์ถ์ํด๋์ค๋ฅผ ์์๋ฐ์ ์์ ํด๋์ค์์ ๋ชจ๋ ์์ ๊ฐ์ํจ์๋ฅผ ๊ตฌํํด์ผ ๊ฐ์ฒด๋ฅผ ๋ง๋ค ์ ์์ด.class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
double getArea() const override {
return 3.14159 * radius * radius;
}
void draw() const override {
cout << "์์ ๊ทธ๋ฆฝ๋๋ค. ๋ฐ์ง๋ฆ: " << radius << endl;
}
};
class Rectangle : public Shape {
private:
double width, height;
public:
Rectangle(double w, double h) : width(w), height(h) {}
double getArea() const override {
return width * height;
}
void draw() const override {
cout << "์ฌ๊ฐํ์ ๊ทธ๋ฆฝ๋๋ค. " << width << "x" << height << endl;
}
};
์ด์ ์ด๋ ๊ฒ ์ฌ์ฉํ ์ ์์ด! ๐จvector<Shape*> shapes;
shapes.push_back(new Circle(5.0));
shapes.push_back(new Rectangle(4.0, 6.0));
shapes.push_back(new Circle(3.0));
for (Shape* shape : shapes) {
shape->draw();
cout << "๋ฉด์ : " << shape->getArea() << endl;
}
// ๋ฉ๋ชจ๋ฆฌ ํด์ ๋ ์์ง ๋ง์!
for (Shape* shape : shapes) {
delete shape;
}
shapes.clear();
์ถ์ํด๋์ค๋ ์ธํฐํ์ด์ค๋ฅผ ์ ์ํ๋ ์ญํ ์ ํด. "์ด ํด๋์ค๋ฅผ ์์๋ฐ์ผ๋ฉด ์ด๋ฐ ๊ธฐ๋ฅ๋ค์ ๋ฐ๋์ ๊ตฌํํด์ผ ํด!"๋ผ๊ณ ๊ฐ์ ํ๋ ๊ฑฐ์ง. ์ด๋ ๊ฒ ํ๋ฉด ์ฝ๋์ ์ผ๊ด์ฑ์ด ์ ์ง๋๊ณ , ์ค์๋ก ์ค์ํ ํจ์๋ฅผ ๊ตฌํ ์ ํ๋ ๊ฑธ ๋ฐฉ์งํ ์ ์์ด! ๐ก๏ธ
๐ฏ ์ธํฐํ์ด์ค ํด๋์ค ํจํด
C++์๋ Java๋ C#์ฒ๋ผ interface ํค์๋๊ฐ ์์ด. ํ์ง๋ง ์์ ๊ฐ์ํจ์๋ง์ผ๋ก ์ด๋ฃจ์ด์ง ์ถ์ํด๋์ค๋ฅผ ๋ง๋ค๋ฉด ์ธํฐํ์ด์ค์ฒ๋ผ ์ฌ์ฉํ ์ ์์ง!// ์ธํฐํ์ด์ค ์ญํ ์ ํ๋ ์ถ์ํด๋์ค
class IDrawable {
public:
virtual void draw() const = 0;
virtual ~IDrawable() {}
};
class IPrintable {
public:
virtual void print() const = 0;
virtual ~IPrintable() {}
};
// ๋ค์ค ์์์ผ๋ก ์ฌ๋ฌ ์ธํฐํ์ด์ค ๊ตฌํ
class Document : public IDrawable, public IPrintable {
private:
string content;
public:
Document(const string& c) : content(c) {}
void draw() const override {
cout << "๋ฌธ์๋ฅผ ํ๋ฉด์ ํ์ํฉ๋๋ค." << endl;
}
void print() const override {
cout << "๋ฌธ์๋ฅผ ํ๋ฆฐํฐ๋ก ์ถ๋ ฅํฉ๋๋ค: " << content << endl;
}
};
์ด๋ฐ ์์ผ๋ก ์ธํฐํ์ด์ค๋ฅผ ์ ์ํ๋ฉด ํด๋์ค ์ค๊ณ๊ฐ ํจ์ฌ ๊น๋ํด์ ธ! ๋ณดํต ์ธํฐํ์ด์ค ํด๋์ค ์ด๋ฆ ์์ 'I'๋ฅผ ๋ถ์ด๋ ๊ฒ ๊ด๋ก์ผ. ๐
๐จ ์ค์ ์์ : ๊ฒ์ ์บ๋ฆญํฐ ์์คํ
// ์ถ์ ๊ธฐ๋ณธ ํด๋์ค
class GameCharacter {
protected:
string name;
int health;
int attackPower;
public:
GameCharacter(const string& n, int hp, int atk)
: name(n), health(hp), attackPower(atk) {}
virtual ~GameCharacter() {}
// ์์ ๊ฐ์ํจ์๋ค
virtual void attack() = 0;
virtual void defend() = 0;
virtual void useSpecialSkill() = 0;
// ์ผ๋ฐ ๊ฐ์ํจ์ (๊ธฐ๋ณธ ๊ตฌํ ์ ๊ณต)
virtual void takeDamage(int damage) {
health -= damage;
if (health < 0) health = 0;
cout << name << "์ด(๊ฐ) " << damage << " ๋ฐ๋ฏธ์ง๋ฅผ ๋ฐ์์ต๋๋ค! ";
cout << "๋จ์ ์ฒด๋ ฅ: " << health << endl;
}
// ์ผ๋ฐ ๋ฉค๋ฒ ํจ์
bool isAlive() const { return health > 0; }
string getName() const { return name; }
int getHealth() const { return health; }
};
// ์ ์ฌ ํด๋์ค
class Warrior : public GameCharacter {
private:
int armor;
public:
Warrior(const string& n)
: GameCharacter(n, 150, 30), armor(20) {}
void attack() override {
cout << name << "์ด(๊ฐ) ๊ฐ๋ ฅํ ๊ฒ ๊ณต๊ฒฉ์ ํฉ๋๋ค! ๐ช" << endl;
cout << "๊ณต๊ฒฉ๋ ฅ: " << attackPower << endl;
}
void defend() override {
cout << name << "์ด(๊ฐ) ๋ฐฉํจ๋ก ๋ฐฉ์ดํฉ๋๋ค! ๐ก๏ธ" << endl;
cout << "๋ฐฉ์ด๋ ฅ: " << armor << endl;
}
void useSpecialSkill() override {
cout << name << "์ ํน์ ์คํฌ: ๊ด์ ์ฌ์ ๋ถ๋
ธ! โ๏ธ" << endl;
cout << "๊ณต๊ฒฉ๋ ฅ์ด 2๋ฐฐ๋ก ์ฆ๊ฐํฉ๋๋ค!" << endl;
}
void takeDamage(int damage) override {
int actualDamage = damage - armor;
if (actualDamage < 0) actualDamage = 0;
GameCharacter::takeDamage(actualDamage);
}
};
// ๋ง๋ฒ์ฌ ํด๋์ค
class Mage : public GameCharacter {
private:
int mana;
public:
Mage(const string& n)
: GameCharacter(n, 80, 50), mana(100) {}
void attack() override {
if (mana >= 10) {
cout << name << "์ด(๊ฐ) ํ์ด์ด๋ณผ์ ์์ ํฉ๋๋ค! ๐ฅ" << endl;
cout << "๋ง๋ฒ ๊ณต๊ฒฉ๋ ฅ: " << attackPower << endl;
mana -= 10;
} else {
cout << "๋ง๋๊ฐ ๋ถ์กฑํฉ๋๋ค!" << endl;
}
}
void defend() override {
cout << name << "์ด(๊ฐ) ๋ง๋ฒ ๋ณดํธ๋ง์ ์์ฑํฉ๋๋ค! โจ" << endl;
mana -= 5;
}
void useSpecialSkill() override {
if (mana >= 50) {
cout << name << "์ ํน์ ์คํฌ: ๋ฉํ
์ค! โ๏ธ" << endl;
cout << "๊ด์ญ ๋ง๋ฒ ๊ณต๊ฒฉ!" << endl;
mana -= 50;
} else {
cout << "๋ง๋๊ฐ ๋ถ์กฑํฉ๋๋ค!" << endl;
}
}
};
// ๊ถ์ ํด๋์ค
class Archer : public GameCharacter {
private:
int arrows;
public:
Archer(const string& n)
: GameCharacter(n, 100, 40), arrows(30) {}
void attack() override {
if (arrows > 0) {
cout << name << "์ด(๊ฐ) ํ์ด์ ๋ฐ์ฌํฉ๋๋ค! ๐น" << endl;
cout << "๊ณต๊ฒฉ๋ ฅ: " << attackPower << endl;
arrows--;
} else {
cout << "ํ์ด์ด ๋จ์ด์ก์ต๋๋ค!" << endl;
}
}
void defend() override {
cout << name << "์ด(๊ฐ) ์ฌ๋น ๋ฅด๊ฒ ํํผํฉ๋๋ค! ๐จ" << endl;
}
void useSpecialSkill() override {
if (arrows >= 5) {
cout << name << "์ ํน์ ์คํฌ: ์ฐ์ ์ฌ๊ฒฉ! ๐ฏ" << endl;
cout << "5๋ฐ์ ํ์ด์ ๋์์ ๋ฐ์ฌ!" << endl;
arrows -= 5;
} else {
cout << "ํ์ด์ด ๋ถ์กฑํฉ๋๋ค!" << endl;
}
}
};
์ด์ ์ด ์บ๋ฆญํฐ๋ค์ ์ฌ์ฉํด๋ณด์! ๐ฎint main() {
// ๋ค์ํ ์บ๋ฆญํฐ ์์ฑ
vector<GameCharacter*> party;
party.push_back(new Warrior("๊ทธ๋กฌ"));
party.push_back(new Mage("์๋ฆฌ๋"));
party.push_back(new Archer("๋ ๊ณ ๋ผ์ค"));
cout << "=== ํํฐ์ ์๊ฐ ===" << endl;
for (auto character : party) {
cout << character->getName() << " (์ฒด๋ ฅ: "
<< character->getHealth() << ")" << endl;
}
cout << "\n=== ์ ํฌ ์์! ===" << endl;
// ๋คํ์ฑ์ ํ! ๊ฐ์ ์ธํฐํ์ด์ค๋ก ๋ค๋ฅธ ๋์
for (auto character : party) {
character->attack();
character->useSpecialSkill();
cout << endl;
}
cout << "=== ์ ์ ๊ณต๊ฒฉ! ===" << endl;
for (auto character : party) {
character->takeDamage(25);
}
// ๋ฉ๋ชจ๋ฆฌ ํด์
for (auto character : party) {
delete character;
}
party.clear();
return 0;
}
1๏ธโฃ GameCharacter* ํฌ์ธํฐ ํ๋๋ก ๋ชจ๋ ์บ๋ฆญํฐ๋ฅผ ๊ด๋ฆฌํ ์ ์์ด!
2๏ธโฃ ์๋ก์ด ์บ๋ฆญํฐ ํด๋์ค๋ฅผ ์ถ๊ฐํด๋ ๊ธฐ์กด ์ฝ๋๋ฅผ ์์ ํ ํ์๊ฐ ์์ด!
3๏ธโฃ ๊ฐ ์บ๋ฆญํฐ๋ ์์ ๋ง์ ํน์ฑ์ ์ ์งํ๋ฉด์๋ ํต์ผ๋ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํด!
์ด๊ฒ ๋ฐ๋ก ๊ฐ๋ฐฉ-ํ์ ์์น(Open-Closed Principle)์ด์ผ! ํ์ฅ์๋ ์ด๋ ค์๊ณ , ์์ ์๋ ๋ซํ์๋ ์ค๊ณ! ๐
๐๏ธ ๋์์ธ ํจํด: ์ค๋ฌด์์ ๋ฐ๋ก ์ฐ๋ ์ค๊ณ ๊ธฐ๋ฒ
C++์์ ๊ฐ์ฒด์งํฅ๊ณผ ๋คํ์ฑ์ ํ์ฉํ ๋ํ์ ์ธ ๋์์ธ ํจํด๋ค์ ์์๋ณด์! ๐จ
1๏ธโฃ ํฉํ ๋ฆฌ ํจํด (Factory Pattern)
๊ฐ์ฒด ์์ฑ์ ์ ๋ดํ๋ ํด๋์ค๋ฅผ ๋ง๋๋ ํจํด์ด์ผ. ๊ฐ์ฒด ์์ฑ ๋ก์ง์ด ๋ณต์กํ๊ฑฐ๋, ์ด๋ค ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ๋ง๋ค์ง ๋ฐํ์์ ๊ฒฐ์ ํด์ผ ํ ๋ ์ ์ฉํด! ๐ญ// ์์์ ๋ง๋ GameCharacter ํด๋์ค๋ค์ ํ์ฉ
class CharacterFactory {
public:
enum CharacterType {
WARRIOR,
MAGE,
ARCHER
};
static GameCharacter* createCharacter(CharacterType type, const string& name) {
switch(type) {
case WARRIOR:
return new Warrior(name);
case MAGE:
return new Mage(name);
case ARCHER:
return new Archer(name);
default:
return nullptr;
}
}
};
// ์ฌ์ฉ ์์
int main() {
// ํฉํ ๋ฆฌ๋ฅผ ํตํด ๊ฐ์ฒด ์์ฑ
GameCharacter* char1 = CharacterFactory::createCharacter(
CharacterFactory::WARRIOR, "์์์ค"
);
GameCharacter* char2 = CharacterFactory::createCharacter(
CharacterFactory::MAGE, "์ ์ด๋"
);
char1->attack();
char2->attack();
delete char1;
delete char2;
return 0;
}
โ ๊ฐ์ฒด ์์ฑ ๋ก์ง์ ํ ๊ณณ์ ์ง์ค์ํฌ ์ ์์ด
โ ํด๋ผ์ด์ธํธ ์ฝ๋๊ฐ ๊ตฌ์ฒด์ ์ธ ํด๋์ค์ ์์กดํ์ง ์์
โ ์๋ก์ด ํ์ ์ ์ถ๊ฐํ๊ธฐ ์ฌ์
โ ๊ฐ์ฒด ์์ฑ ๊ณผ์ ์ด ๋ณต์กํด๋ ํด๋ผ์ด์ธํธ๋ ๊ฐ๋จํ๊ฒ ์ฌ์ฉ ๊ฐ๋ฅ!
2๏ธโฃ ์ ๋ต ํจํด (Strategy Pattern)
์๊ณ ๋ฆฌ์ฆ์ ์บก์ํํด์ ๋ฐํ์์ ๊ต์ฒดํ ์ ์๊ฒ ๋ง๋๋ ํจํด์ด์ผ. ๊ฐ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ์ฌ๋ฌ ๋ฐฉ๋ฒ์ด ์์ ๋ ์ ์ฉํด! ๐ฏ// ๊ณต๊ฒฉ ์ ๋ต ์ธํฐํ์ด์ค
class AttackStrategy {
public:
virtual ~AttackStrategy() {}
virtual void execute() = 0;
};
// ๊ตฌ์ฒด์ ์ธ ์ ๋ต๋ค
class MeleeAttack : public AttackStrategy {
public:
void execute() override {
cout << "๊ทผ์ ๊ณต๊ฒฉ! ๊ฒ์ผ๋ก ๋ฒ ๊ธฐ! โ๏ธ" << endl;
}
};
class RangedAttack : public AttackStrategy {
public:
void execute() override {
cout << "์๊ฑฐ๋ฆฌ ๊ณต๊ฒฉ! ํ์ด ๋ฐ์ฌ! ๐น" << endl;
}
};
class MagicAttack : public AttackStrategy {
public:
void execute() override {
cout << "๋ง๋ฒ ๊ณต๊ฒฉ! ํ์ด์ด๋ณผ! ๐ฅ" << endl;
}
};
// ์ ๋ต์ ์ฌ์ฉํ๋ ์บ๋ฆญํฐ
class StrategicCharacter {
private:
string name;
AttackStrategy* strategy;
public:
StrategicCharacter(const string& n) : name(n), strategy(nullptr) {}
~StrategicCharacter() {
if (strategy) delete strategy;
}
void setAttackStrategy(AttackStrategy* newStrategy) {
if (strategy) delete strategy;
strategy = newStrategy;
}
void performAttack() {
if (strategy) {
cout << name << "์ ๊ณต๊ฒฉ: ";
strategy->execute();
} else {
cout << "๊ณต๊ฒฉ ์ ๋ต์ด ์ค์ ๋์ง ์์์ต๋๋ค!" << endl;
}
}
};
// ์ฌ์ฉ ์์
int main() {
StrategicCharacter hero("์ฉ์ฌ");
// ์ํฉ์ ๋ฐ๋ผ ์ ๋ต ๋ณ๊ฒฝ
cout << "=== 1๋จ๊ณ: ๊ทผ์ ์ ํฌ ===" << endl;
hero.setAttackStrategy(new MeleeAttack());
hero.performAttack();
cout << "\n=== 2๋จ๊ณ: ์๊ฑฐ๋ฆฌ ์ ํฌ ===" << endl;
hero.setAttackStrategy(new RangedAttack());
hero.performAttack();
cout << "\n=== 3๋จ๊ณ: ๋ง๋ฒ ์ ํฌ ===" << endl;
hero.setAttackStrategy(new MagicAttack());
hero.performAttack();
return 0;
}
์ ๋ต ํจํด์ ์ ๋ง ์ ์ฉํด! ํนํ ๊ฒ์์ด๋ ์๋ฎฌ๋ ์ด์
ํ๋ก๊ทธ๋จ์์ AI ํ๋์ ๊ตฌํํ ๋ ๋ง์ด ์จ. ๐ค
3๏ธโฃ ์ต์ ๋ฒ ํจํด (Observer Pattern)
ํ ๊ฐ์ฒด์ ์ํ๊ฐ ๋ณ๊ฒฝ๋๋ฉด ๊ทธ๊ฒ์ ์์กดํ๋ ๋ค๋ฅธ ๊ฐ์ฒด๋ค์๊ฒ ์๋์ผ๋ก ์๋ ค์ฃผ๋ ํจํด์ด์ผ. ์ด๋ฒคํธ ์ฒ๋ฆฌ ์์คํ ์์ ์ ๋ง ๋ง์ด ์ฌ์ฉ๋ผ! ๐ข// ์ต์ ๋ฒ ์ธํฐํ์ด์ค
class Observer {
public:
virtual ~Observer() {}
virtual void update(const string& message) = 0;
};
// ์ฃผ์ฒด(Subject) ํด๋์ค
class Subject {
private:
vector<Observer*> observers;
string state;
public:
void attach(Observer* observer) {
observers.push_back(observer);
}
void detach(Observer* observer) {
observers.erase(
remove(observers.begin(), observers.end(), observer),
observers.end()
);
}
void notify() {
for (Observer* observer : observers) {
observer->update(state);
}
}
void setState(const string& newState) {
state = newState;
cout << "์ํ ๋ณ๊ฒฝ: " << state << endl;
notify(); // ๋ชจ๋ ์ต์ ๋ฒ์๊ฒ ์๋ฆผ!
}
string getState() const { return state; }
};
// ๊ตฌ์ฒด์ ์ธ ์ต์ ๋ฒ๋ค
class Player : public Observer {
private:
string name;
public:
Player(const string& n) : name(n) {}
void update(const string& message) override {
cout << "[ํ๋ ์ด์ด " << name << "] ์๋ฆผ ๋ฐ์: "
<< message << " ๐ฎ" << endl;
}
};
class UIDisplay : public Observer {
public:
void update(const string& message) override {
cout << "[UI ๋์คํ๋ ์ด] ํ๋ฉด ์
๋ฐ์ดํธ: "
<< message << " ๐ฅ๏ธ" << endl;
}
};
class SoundSystem : public Observer {
public:
void update(const string& message) override {
cout << "[์ฌ์ด๋ ์์คํ
] ํจ๊ณผ์ ์ฌ์: "
<< message << " ๐" << endl;
}
};
// ์ฌ์ฉ ์์
int main() {
Subject gameState;
Player player1("์ฒ ์");
Player player2("์ํฌ");
UIDisplay ui;
SoundSystem sound;
// ์ต์ ๋ฒ ๋ฑ๋ก
gameState.attach(&player1);
gameState.attach(&player2);
gameState.attach(&ui);
gameState.attach(&sound);
cout << "=== ๊ฒ์ ์์ ===" << endl;
gameState.setState("๊ฒ์ ์์!");
cout << "\n=== ์ ์ถํ ===" << endl;
gameState.setState("๋ณด์ค ๋ฑ์ฅ!");
cout << "\n=== ํ๋ ์ด์ด2 ํด์ฅ ===" << endl;
gameState.detach(&player2);
gameState.setState("์์ดํ
ํ๋!");
return 0;
}
์ต์ ๋ฒ ํจํด์ GUI ํ๋ก๊ทธ๋๋ฐ, ๊ฒ์ ๊ฐ๋ฐ, ์ด๋ฒคํธ ๊ธฐ๋ฐ ์์คํ
์์ ํ์์ ์ด์ผ! ๐ฏ
๐ญ ๋ ๋ง์ ๋์์ธ ํจํด๋ค
4๏ธโฃ ์ฑ๊ธํค ํจํด (Singleton Pattern)
ํด๋์ค์ ์ธ์คํด์ค๊ฐ ์ค์ง ํ๋๋ง ์กด์ฌํ๋๋ก ๋ณด์ฅํ๋ ํจํด์ด์ผ. ๊ฒ์์ ๊ฒ์ ๋งค๋์ , ์ค์ ๊ด๋ฆฌ์, ๋ก๊ทธ ์์คํ ๊ฐ์ ๊ณณ์์ ๋ง์ด ์จ! ๐ฏclass GameManager {
private:
static GameManager* instance;
int score;
int level;
// private ์์ฑ์๋ก ์ธ๋ถ ์์ฑ ์ฐจ๋จ!
GameManager() : score(0), level(1) {
cout << "๊ฒ์ ๋งค๋์ ์ด๊ธฐํ" << endl;
}
// ๋ณต์ฌ ์์ฑ์์ ๋์
์ฐ์ฐ์ ์ญ์
GameManager(const GameManager&) = delete;
GameManager& operator=(const GameManager&) = delete;
public:
static GameManager* getInstance() {
if (instance == nullptr) {
instance = new GameManager();
}
return instance;
}
static void destroyInstance() {
if (instance != nullptr) {
delete instance;
instance = nullptr;
}
}
void addScore(int points) {
score += points;
cout << "์ ์ ํ๋! ํ์ฌ ์ ์: " << score << endl;
}
void levelUp() {
level++;
cout << "๋ ๋ฒจ ์
! ํ์ฌ ๋ ๋ฒจ: " << level << endl;
}
int getScore() const { return score; }
int getLevel() const { return level; }
};
// static ๋ฉค๋ฒ ์ด๊ธฐํ
GameManager* GameManager::instance = nullptr;
// ์ฌ์ฉ ์์
int main() {
// ์ด๋์๋ ๊ฐ์ ์ธ์คํด์ค ์ ๊ทผ!
GameManager* gm1 = GameManager::getInstance();
gm1->addScore(100);
GameManager* gm2 = GameManager::getInstance();
gm2->levelUp();
// gm1๊ณผ gm2๋ ๊ฐ์ ๊ฐ์ฒด!
cout << "gm1 ์ ์: " << gm1->getScore() << endl;
cout << "gm2 ์ ์: " << gm2->getScore() << endl;
GameManager::destroyInstance();
return 0;
}
์ฑ๊ธํค์ ํธ๋ฆฌํ์ง๋ง ๋จ์ฉํ๋ฉด ์ ๋ผ! ์ ์ญ ์ํ๋ฅผ ๋ง๋ค๊ธฐ ๋๋ฌธ์ ํ ์คํธํ๊ธฐ ์ด๋ ต๊ณ , ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์ ๋ฌธ์ ๊ฐ ์๊ธธ ์ ์์ด. ์ ์ฝ๋๋ ์ค๋ ๋ ์์ ํ์ง ์์ผ๋, ์ค์ ํ๋ก์ ํธ์์๋ std::mutex๋ std::call_once๋ฅผ ์ฌ์ฉํด์ผ ํด! ๐
5๏ธโฃ ํ ํ๋ฆฟ ๋ฉ์๋ ํจํด (Template Method Pattern)
์๊ณ ๋ฆฌ์ฆ์ ๊ณจ๊ฒฉ์ ์ ์ํ๊ณ , ์ผ๋ถ ๋จ๊ณ๋ฅผ ์๋ธํด๋์ค์์ ๊ตฌํํ๊ฒ ํ๋ ํจํด์ด์ผ. ์ฝ๋ ์ฌ์ฌ์ฉ์ฑ์ด ์ ๋ง ์ข์์ ธ! ๐class DataProcessor {
public:
// ํ
ํ๋ฆฟ ๋ฉ์๋: ์๊ณ ๋ฆฌ์ฆ์ ๊ณจ๊ฒฉ
void process() {
loadData();
validateData();
processData();
saveData();
cleanup();
}
virtual ~DataProcessor() {}
protected:
// ์๋ธํด๋์ค์์ ๊ตฌํํ ์์ ๊ฐ์ํจ์๋ค
virtual void loadData() = 0;
virtual void processData() = 0;
virtual void saveData() = 0;
// ๊ธฐ๋ณธ ๊ตฌํ์ ์ ๊ณตํ๋ ๊ฐ์ํจ์
virtual void validateData() {
cout << "๋ฐ์ดํฐ ์ ํจ์ฑ ๊ฒ์ฌ ์ค..." << endl;
}
virtual void cleanup() {
cout << "์ ๋ฆฌ ์์
์๋ฃ" << endl;
}
};
class CSVProcessor : public DataProcessor {
protected:
void loadData() override {
cout << "CSV ํ์ผ ๋ก๋ฉ ์ค... ๐" << endl;
}
void processData() override {
cout << "CSV ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์ค... โ๏ธ" << endl;
}
void saveData() override {
cout << "CSV ํ์ผ๋ก ์ ์ฅ ์ค... ๐พ" << endl;
}
};
class JSONProcessor : public DataProcessor {
protected:
void loadData() override {
cout << "JSON ํ์ผ ๋ก๋ฉ ์ค... ๐" << endl;
}
void processData() override {
cout << "JSON ๋ฐ์ดํฐ ํ์ฑ ๋ฐ ์ฒ๋ฆฌ ์ค... โ๏ธ" << endl;
}
void saveData() override {
cout << "JSON ํ์ผ๋ก ์ ์ฅ ์ค... ๐พ" << endl;
}
// ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ค๋ฒ๋ผ์ด๋
void validateData() override {
cout << "JSON ์คํค๋ง ๊ฒ์ฆ ์ค... โ
" << endl;
}
};
// ์ฌ์ฉ ์์
int main() {
cout << "=== CSV ์ฒ๋ฆฌ ===" << endl;
DataProcessor* csv = new CSVProcessor();
csv->process();
cout << "\n=== JSON ์ฒ๋ฆฌ ===" << endl;
DataProcessor* json = new JSONProcessor();
json->process();
delete csv;
delete json;
return 0;
}
ํ
ํ๋ฆฟ ๋ฉ์๋ ํจํด์ ๊ณตํต ๋ก์ง์ ๋ถ๋ชจ ํด๋์ค์ ๋๊ณ , ๋ณํ๋ ๋ถ๋ถ๋ง ์์ ํด๋์ค์์ ๊ตฌํํ๊ฒ ํด. ์ฝ๋ ์ค๋ณต์ ํ ์ค์ผ ์ ์์ด! ๐จ
6๏ธโฃ ๋ฐ์ฝ๋ ์ดํฐ ํจํด (Decorator Pattern)
๊ฐ์ฒด์ ๋์ ์ผ๋ก ์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ ํจํด์ด์ผ. ์์ ๋์ ์กฐํฉ์ ์ฌ์ฉํด์ ์ ์ฐ์ฑ์ด ํจ์ฌ ์ข์! ๐// ๊ธฐ๋ณธ ์ปดํฌ๋ํธ ์ธํฐํ์ด์ค
class Weapon {
public:
virtual ~Weapon() {}
virtual string getDescription() const = 0;
virtual int getDamage() const = 0;
};
// ๊ธฐ๋ณธ ๋ฌด๊ธฐ
class BasicSword : public Weapon {
public:
string getDescription() const override {
return "๊ธฐ๋ณธ ๊ฒ";
}
int getDamage() const override {
return 10;
}
};
// ๋ฐ์ฝ๋ ์ดํฐ ๊ธฐ๋ณธ ํด๋์ค
class WeaponDecorator : public Weapon {
protected:
Weapon* weapon;
public:
WeaponDecorator(Weapon* w) : weapon(w) {}
virtual ~WeaponDecorator() { delete weapon; }
};
// ๊ตฌ์ฒด์ ์ธ ๋ฐ์ฝ๋ ์ดํฐ๋ค
class FireEnchantment : public WeaponDecorator {
public:
FireEnchantment(Weapon* w) : WeaponDecorator(w) {}
string getDescription() const override {
return weapon->getDescription() + " + ํ์ผ ๊ฐํ ๐ฅ";
}
int getDamage() const override {
return weapon->getDamage() + 15;
}
};
class PoisonEnchantment : public WeaponDecorator {
public:
PoisonEnchantment(Weapon* w) : WeaponDecorator(w) {}
string getDescription() const override {
return weapon->getDescription() + " + ๋
๊ฐํ โ ๏ธ";
}
int getDamage() const override {
return weapon->getDamage() + 10;
}
};
class SharpnessEnchantment : public WeaponDecorator {
public:
SharpnessEnchantment(Weapon* w) : WeaponDecorator(w) {}
string getDescription() const override {
return weapon->getDescription() + " + ๋ ์นด๋ก์ ๊ฐํ โ๏ธ";
}
int getDamage() const override {
return weapon->getDamage() + 8;
}
};
// ์ฌ์ฉ ์์
int main() {
// ๊ธฐ๋ณธ ๊ฒ
Weapon* sword = new BasicSword();
cout << sword->getDescription() << endl;
cout << "๊ณต๊ฒฉ๋ ฅ: " << sword->getDamage() << endl << endl;
// ํ์ผ ๊ฐํ ์ถ๊ฐ
Weapon* fireSword = new FireEnchantment(new BasicSword());
cout << fireSword->getDescription() << endl;
cout << "๊ณต๊ฒฉ๋ ฅ: " << fireSword->getDamage() << endl << endl;
// ์ฌ๋ฌ ๊ฐํ ์ค์ฒฉ!
Weapon* ultimateSword = new SharpnessEnchantment(
new PoisonEnchantment(
new FireEnchantment(
new BasicSword()
)
)
);
cout << ultimateSword->getDescription() << endl;
cout << "๊ณต๊ฒฉ๋ ฅ: " << ultimateSword->getDamage() << endl;
delete sword;
delete fireSword;
delete ultimateSword;
return 0;
}
๋ฐ์ฝ๋ ์ดํฐ ํจํด์ ์ ๋ง ๊ฐ๋ ฅํด! ๋ฐํ์์ ๊ธฐ๋ฅ์ ์์ ๋กญ๊ฒ ์กฐํฉํ ์ ์๊ฑฐ๋ . ๊ฒ์ ์์ดํ
์์คํ
, UI ์ปดํฌ๋ํธ ๊พธ๋ฏธ๊ธฐ ๋ฑ์ ์๋ฒฝํด! ๐จ
๐งฉ SOLID ์์น๊ณผ ๊ฐ์ฒด์งํฅ ์ค๊ณ
| ์์น | ์ค๋ช | ํต์ฌ ๊ฐ๋ |
|---|---|---|
| SRP ๋จ์ผ ์ฑ ์ |
ํด๋์ค๋ ํ๋์ ์ฑ ์๋ง ๊ฐ์ ธ์ผ ํด | ํ ํด๋์ค๋ ํ ๊ฐ์ง ์ด์ ๋ก๋ง ๋ณ๊ฒฝ๋์ด์ผ ํจ |
| OCP ๊ฐ๋ฐฉ-ํ์ |
ํ์ฅ์๋ ์ด๋ ค์๊ณ ์์ ์๋ ๋ซํ์์ด์ผ ํด | ์ ๊ธฐ๋ฅ ์ถ๊ฐ ์ ๊ธฐ์กด ์ฝ๋ ์์ ์ต์ํ |
| LSP ๋ฆฌ์ค์ฝํ ์นํ |
์์ ํด๋์ค๋ ๋ถ๋ชจ ํด๋์ค๋ฅผ ๋์ฒดํ ์ ์์ด์ผ ํด | ๋คํ์ฑ์ ๊ธฐ๋ณธ ์์น |
| ISP ์ธํฐํ์ด์ค ๋ถ๋ฆฌ |
ํด๋ผ์ด์ธํธ๋ ์ฌ์ฉํ์ง ์๋ ์ธํฐํ์ด์ค์ ์์กดํ๋ฉด ์ ๋ผ | ์๊ณ ๊ตฌ์ฒด์ ์ธ ์ธํฐํ์ด์ค๊ฐ ์ข์ |
| DIP ์์กด์ฑ ์ญ์ |
๊ตฌ์ฒด์ ์ธ ๊ฒ์ด ์๋ ์ถ์์ ์ธ ๊ฒ์ ์์กดํด์ผ ํด | ๊ณ ์์ค ๋ชจ๋์ด ์ ์์ค ๋ชจ๋์ ์์กดํ๋ฉด ์ ๋จ |
๐ฏ SOLID ์์น ์ค์ ์์
1๏ธโฃ ๋จ์ผ ์ฑ ์ ์์น (SRP) ์๋ฐ ์์์ ๊ฐ์// โ ๋์ ์: ์ฌ๋ฌ ์ฑ
์์ ๊ฐ์ง ํด๋์ค
class User {
private:
string name;
string email;
public:
void setName(const string& n) { name = n; }
void setEmail(const string& e) { email = e; }
// ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ์ฅ (์ฑ
์ 1)
void saveToDatabase() {
cout << "DB์ ์ ์ฅ..." << endl;
}
// ์ด๋ฉ์ผ ์ ์ก (์ฑ
์ 2)
void sendEmail(const string& message) {
cout << "์ด๋ฉ์ผ ์ ์ก..." << endl;
}
// ๋ก๊ทธ ๊ธฐ๋ก (์ฑ
์ 3)
void log(const string& action) {
cout << "๋ก๊ทธ: " << action << endl;
}
};
// โ
์ข์ ์: ์ฑ
์์ ๋ถ๋ฆฌ
class User {
private:
string name;
string email;
public:
void setName(const string& n) { name = n; }
void setEmail(const string& e) { email = e; }
string getName() const { return name; }
string getEmail() const { return email; }
};
class UserRepository {
public:
void save(const User& user) {
cout << "DB์ " << user.getName() << " ์ ์ฅ" << endl;
}
};
class EmailService {
public:
void send(const User& user, const string& message) {
cout << user.getEmail() << "๋ก ์ด๋ฉ์ผ ์ ์ก" << endl;
}
};
class Logger {
public:
void log(const string& action) {
cout << "๋ก๊ทธ: " << action << endl;
}
};
์ด๋ ๊ฒ ์ฑ
์์ ๋ถ๋ฆฌํ๋ฉด ๊ฐ ํด๋์ค๊ฐ ํ๋์ ์ด์ ๋ก๋ง ๋ณ๊ฒฝ๋ผ. ์ ์ง๋ณด์๊ฐ ํจ์ฌ ์ฌ์์ง์ง! ๐ฏ2๏ธโฃ ๊ฐ๋ฐฉ-ํ์ ์์น (OCP) ์ ์ฉ
// โ
OCP๋ฅผ ๋ฐ๋ฅด๋ ์ค๊ณ
class Shape {
public:
virtual ~Shape() {}
virtual double calculateArea() const = 0;
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
double calculateArea() const override {
return 3.14159 * radius * radius;
}
};
class Rectangle : public Shape {
private:
double width, height;
public:
Rectangle(double w, double h) : width(w), height(h) {}
double calculateArea() const override {
return width * height;
}
};
// ์๋ก์ด ๋ํ ์ถ๊ฐ ์ ๊ธฐ์กด ์ฝ๋ ์์ ๋ถํ์!
class Triangle : public Shape {
private:
double base, height;
public:
Triangle(double b, double h) : base(b), height(h) {}
double calculateArea() const override {
return 0.5 * base * height;
}
};
class AreaCalculator {
public:
double calculateTotalArea(const vector<Shape*>& shapes) {
double total = 0;
for (const Shape* shape : shapes) {
total += shape->calculateArea();
}
return total;
}
};
์๋ก์ด ๋ํ์ ์ถ๊ฐํด๋ AreaCalculator ํด๋์ค๋ ์ ํ ์์ ํ ํ์๊ฐ ์์ด! ์ด๊ฒ ๋ฐ๋ก OCP์ ํ์ด์ผ! ๐ช3๏ธโฃ ์์กด์ฑ ์ญ์ ์์น (DIP) ์ ์ฉ
// โ ๋์ ์: ๊ตฌ์ฒด ํด๋์ค์ ์์กด
class MySQLDatabase {
public:
void connect() { cout << "MySQL ์ฐ๊ฒฐ" << endl; }
void query(const string& sql) { cout << "์ฟผ๋ฆฌ ์คํ: " << sql << endl; }
};
class UserService {
private:
MySQLDatabase db; // ๊ตฌ์ฒด ํด๋์ค์ ์ง์ ์์กด!
public:
void getUser(int id) {
db.connect();
db.query("SELECT * FROM users WHERE id = " + to_string(id));
}
};
// โ
์ข์ ์: ์ถ์ํ์ ์์กด
class IDatabase {
public:
virtual ~IDatabase() {}
virtual void connect() = 0;
virtual void query(const string& sql) = 0;
};
class MySQLDatabase : public IDatabase {
public:
void connect() override { cout << "MySQL ์ฐ๊ฒฐ" << endl; }
void query(const string& sql) override {
cout << "MySQL ์ฟผ๋ฆฌ: " << sql << endl;
}
};
class PostgreSQLDatabase : public IDatabase {
public:
void connect() override { cout << "PostgreSQL ์ฐ๊ฒฐ" << endl; }
void query(const string& sql) override {
cout << "PostgreSQL ์ฟผ๋ฆฌ: " << sql << endl;
}
};
class UserService {
private:
IDatabase* db; // ์ถ์ํ์ ์์กด!
public:
UserService(IDatabase* database) : db(database) {}
void getUser(int id) {
db->connect();
db->query("SELECT * FROM users WHERE id = " + to_string(id));
}
};
// ์ฌ์ฉ ์์
int main() {
// ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ฝ๊ฒ ๊ต์ฒด ๊ฐ๋ฅ!
IDatabase* mysql = new MySQLDatabase();
UserService service1(mysql);
service1.getUser(1);
IDatabase* postgres = new PostgreSQLDatabase();
UserService service2(postgres);
service2.getUser(2);
delete mysql;
delete postgres;
return 0;
}
DIP๋ฅผ ์ ์ฉํ๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ MySQL์์ PostgreSQL๋ก ๋ฐ๊ฟ๋ UserService ์ฝ๋๋ ์ ํ ์์ ํ ํ์๊ฐ ์์ด! ๐
๐ ์ค๋ฌด ํ๋ก์ ํธ ์์ : ๊ฒ์ ์์ง ์ค๊ณ
// ========== ์ปดํฌ๋ํธ ์์คํ
==========
class Component {
public:
virtual ~Component() {}
virtual void update(float deltaTime) = 0;
virtual string getType() const = 0;
};
class TransformComponent : public Component {
private:
float x, y;
float rotation;
public:
TransformComponent(float px = 0, float py = 0)
: x(px), y(py), rotation(0) {}
void update(float deltaTime) override {
// ์์น ์
๋ฐ์ดํธ ๋ก์ง
}
string getType() const override { return "Transform"; }
void setPosition(float px, float py) { x = px; y = py; }
void move(float dx, float dy) { x += dx; y += dy; }
float getX() const { return x; }
float getY() const { return y; }
};
class RenderComponent : public Component {
private:
string spriteName;
public:
RenderComponent(const string& sprite) : spriteName(sprite) {}
void update(float deltaTime) override {
// ๋ ๋๋ง ๋ก์ง
cout << "๋ ๋๋ง: " << spriteName << endl;
}
string getType() const override { return "Render"; }
};
class PhysicsComponent : public Component {
private:
float velocityX, velocityY;
float mass;
public:
PhysicsComponent(float m = 1.0f)
: velocityX(0), velocityY(0), mass(m) {}
void update(float deltaTime) override {
// ๋ฌผ๋ฆฌ ์๋ฎฌ๋ ์ด์
}
string getType() const override { return "Physics"; }
void applyForce(float fx, float fy) {
velocityX += fx / mass;
velocityY += fy / mass;
}
};
// ========== ๊ฒ์ ์ค๋ธ์ ํธ ==========
class GameObject {
private:
string name;
vector<Component*> components;
bool active;
public:
GameObject(const string& n) : name(n), active(true) {}
~GameObject() {
for (Component* comp : components) {
delete comp;
}
}
void addComponent(Component* component) {
components.push_back(component);
}
template<typename T>
T* getComponent() {
for (Component* comp : components) {
T* result = dynamic_cast<T*>(comp);
if (result != nullptr) {
return result;
}
}
return nullptr;
}
void update(float deltaTime) {
if (!active) return;
for (Component* comp : components) {
comp->update(deltaTime);
}
}
void setActive(bool isActive) { active = isActive; }
bool isActive() const { return active; }
string getName() const { return name; }
};
// ========== ์ฌ ๊ด๋ฆฌ ==========
class Scene {
private:
string name;
vector<GameObject*> gameObjects;
public:
Scene(const string& n) : name(n) {}
~Scene() {
for (GameObject* obj : gameObjects) {
delete obj;
}
}
void addGameObject(GameObject* obj) {
gameObjects.push_back(obj);
}
void update(float deltaTime) {
for (GameObject* obj : gameObjects) {
if (obj->isActive()) {
obj->update(deltaTime);
}
}
}
GameObject* findGameObject(const string& name) {
for (GameObject* obj : gameObjects) {
if (obj->getName() == name) {
return obj;
}
}
return nullptr;
}
string getName() const { return name; }
};
// ========== ๊ฒ์ ์์ง (์ฑ๊ธํค) ==========
class GameEngine {
private:
static GameEngine* instance;
Scene* currentScene;
bool running;
GameEngine() : currentScene(nullptr), running(false) {}
public:
static GameEngine* getInstance() {
if (instance == nullptr) {
instance = new GameEngine();
}
return instance;
}
void loadScene(Scene* scene) {
if (currentScene != nullptr) {
delete currentScene;
}
currentScene = scene;
cout << "์ฌ ๋ก๋: " << scene->getName() << " ๐ฌ" << endl;
}
void start() {
running = true;
cout << "๊ฒ์ ์์! ๐ฎ" << endl;
}
void update(float deltaTime) {
if (running && currentScene != nullptr) {
currentScene->update(deltaTime);
}
}
void stop() {
running = false;
cout << "๊ฒ์ ์ข
๋ฃ! ๐" << endl;
}
Scene* getCurrentScene() { return currentScene; }
};
GameEngine* GameEngine::instance = nullptr;
// ========== ์ฌ์ฉ ์์ ==========
int main() {
GameEngine* engine = GameEngine::getInstance();
// ์ฌ ์์ฑ
Scene* mainScene = new Scene("๋ฉ์ธ ๊ฒ์");
// ํ๋ ์ด์ด ์ค๋ธ์ ํธ ์์ฑ
GameObject* player = new GameObject("ํ๋ ์ด์ด");
player->addComponent(new TransformComponent(100, 100));
player->addComponent(new RenderComponent("player_sprite.png"));
player->addComponent(new PhysicsComponent(1.5f));
mainScene->addGameObject(player);
// ์ ์ค๋ธ์ ํธ ์์ฑ
GameObject* enemy = new GameObject("์ ");
enemy->addComponent(new TransformComponent(300, 200));
enemy->addComponent(new RenderComponent("enemy_sprite.png"));
enemy->addComponent(new PhysicsComponent(1.0f));
mainScene->addGameObject(enemy);
// ๋ฐฐ๊ฒฝ ์ค๋ธ์ ํธ
GameObject* background = new GameObject("๋ฐฐ๊ฒฝ");
background->addComponent(new TransformComponent(0, 0));
background->addComponent(new RenderComponent("background.png"));
mainScene->addGameObject(background);
// ๊ฒ์ ์คํ
engine->loadScene(mainScene);
engine->start();
// ๊ฒ์ ๋ฃจํ ์๋ฎฌ๋ ์ด์
cout << "\n=== ๊ฒ์ ๋ฃจํ ์์ ===" << endl;
for (int i = 0; i < 3; i++) {
cout << "\n--- ํ๋ ์ " << i + 1 << " ---" << endl;
engine->update(0.016f); // ์ฝ 60 FPS
// ํ๋ ์ด์ด ์ด๋
TransformComponent* playerTransform =
player->getComponent<TransformComponent>();
if (playerTransform) {
playerTransform->move(10, 0);
cout << "ํ๋ ์ด์ด ์์น: ("
<< playerTransform->getX() << ", "
<< playerTransform->getY() << ")" << endl;
}
}
engine->stop();
return 0;
}
โ ์ปดํฌ๋ํธ ํจํด: ๊ธฐ๋ฅ์ ๋ ๋ฆฝ์ ์ธ ์ปดํฌ๋ํธ๋ก ๋ถ๋ฆฌ
โ ์ฑ๊ธํค ํจํด: ๊ฒ์ ์์ง์ ํ๋๋ง ์กด์ฌ
โ ๋คํ์ฑ ํ์ฉ: Component ์ธํฐํ์ด์ค๋ก ๋ค์ํ ์ปดํฌ๋ํธ ๊ด๋ฆฌ
โ SOLID ์์น ์ค์: ๊ฐ ํด๋์ค๊ฐ ๋ช ํํ ์ฑ ์์ ๊ฐ์ง
โ ํ์ฅ์ฑ: ์๋ก์ด ์ปดํฌ๋ํธ ํ์ ์ ์ฝ๊ฒ ์ถ๊ฐ ๊ฐ๋ฅ!
์ด๋ฐ ๊ตฌ์กฐ๋ Unity๋ Unreal Engine ๊ฐ์ ์ค์ ๊ฒ์ ์์ง์์๋ ์ฌ์ฉํ๋ ํจํด์ด์ผ! ๐ฎ
๐ก ์ค๋ฌด ํ๊ณผ ๋ฒ ์คํธ ํ๋ํฐ์ค
1๏ธโฃ ๊ฐ์ํจ์ ์ฑ๋ฅ ๊ณ ๋ ค์ฌํญ
๊ฐ์ํจ์๋ ํธ๋ฆฌํ์ง๋ง ์ฝ๊ฐ์ ์ฑ๋ฅ ์ค๋ฒํค๋๊ฐ ์์ด. vtable์ ํตํ ๊ฐ์ ํธ์ถ์ด ์ผ๋ฐ ํจ์ ํธ์ถ๋ณด๋ค ๋๋ฆฌ๊ฑฐ๋ . ํ์ง๋ง ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ์ด ์ฐจ์ด๋ ๋ฌด์ํ ์ ์๋ ์์ค์ด์ผ! ๐// ์ฑ๋ฅ์ด ์ ๋ง ์ค์ํ ๊ฒฝ์ฐ
class FastObject {
public:
// final์ ๋ถ์ด๋ฉด ์ปดํ์ผ๋ฌ๊ฐ ์ต์ ํ ๊ฐ๋ฅ!
virtual void criticalFunction() final {
// ์ฑ๋ฅ ์ค์ํ ์ฝ๋
}
};
// ๋๋ ํ
ํ๋ฆฟ์ผ๋ก ์ปดํ์ผ ํ์ ๋คํ์ฑ ํ์ฉ
template<typename T>
class OptimizedContainer {
public:
void process(T& item) {
item.doSomething(); // ๊ฐ์ํจ์ ํธ์ถ ์์!
}
};
2๏ธโฃ ์ค๋งํธ ํฌ์ธํฐ ํ์ฉํ๊ธฐ
๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ๋ C++์์ ์ ๋ง ์ค์ํด! ์์ฆ์ new/delete ๋์ ์ค๋งํธ ํฌ์ธํฐ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ ํ์ค์ด์ผ. ๐ฏ#include <memory>
class ModernGameObject {
private:
vector<unique_ptr<Component>> components; // ์๋ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ!
public:
void addComponent(unique_ptr<Component> comp) {
components.push_back(move(comp));
}
// ์๋ฉธ์์์ delete ํ ํ์ ์์!
~ModernGameObject() = default;
};
// ์ฌ์ฉ ์์
int main() {
auto obj = make_unique<ModernGameObject>();
obj->addComponent(make_unique<TransformComponent>(0, 0));
obj->addComponent(make_unique<RenderComponent>("sprite.png"));
// obj๊ฐ ์ค์ฝํ๋ฅผ ๋ฒ์ด๋๋ฉด ์๋์ผ๋ก ๋ฉ๋ชจ๋ฆฌ ํด์ !
return 0;
}
๐น unique_ptr: ๋จ๋ ์์ ๊ถ, ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉ
๐น shared_ptr: ๊ณต์ ์์ ๊ถ, ์ฐธ์กฐ ์นด์ดํ
๐น weak_ptr: ์ํ ์ฐธ์กฐ ๋ฐฉ์ง์ฉ
๋๋ถ๋ถ์ ๊ฒฝ์ฐ unique_ptr๋ก ์ถฉ๋ถํด! ํ์ํ ๋๋ง shared_ptr์ ์ฌ์ฉํ์. ๐ฏ
3๏ธโฃ ์ธํฐํ์ด์ค ์ค๊ณ ์์น
์ข์ ์ธํฐํ์ด์ค๋ฅผ ์ค๊ณํ๋ ๊ฑด ์ ๋ง ์ค์ํด! ๋ช ๊ฐ์ง ์์น์ ์๋ ค์ค๊ฒ. ๐โ DO: ์๊ณ ์ง์ค๋ ์ธํฐํ์ด์ค
// ์ข์ ์: ๊ฐ ์ธํฐํ์ด์ค๊ฐ ๋ช
ํํ ์ญํ
class IMovable {
public:
virtual void move(float dx, float dy) = 0;
virtual ~IMovable() {}
};
class IRenderable {
public:
virtual void render() = 0;
virtual ~IRenderable() {}
};
class ICollidable {
public:
virtual bool checkCollision(const ICollidable& other) = 0;
virtual ~ICollidable() {}
};
โ DON'T: ๊ฑฐ๋ํ ์ธํฐํ์ด์ค// ๋์ ์: ๋๋ฌด ๋ง์ ์ฑ
์
class IGameObject {
public:
virtual void move(float dx, float dy) = 0;
virtual void render() = 0;
virtual bool checkCollision(const IGameObject& other) = 0;
virtual void playSound() = 0;
virtual void updateAI() = 0;
virtual void saveToFile() = 0;
// ... ๋๋ฌด ๋ง์!
};
4๏ธโฃ ์์ธ ์์ ์ฑ ๋ณด์ฅ
๊ฐ์ํจ์๋ฅผ ์ฌ์ฉํ ๋ ์์ธ ์ฒ๋ฆฌ๋ ์ ๊ฒฝ ์จ์ผ ํด! ๐ก๏ธclass SafeComponent : public Component {
public:
void update(float deltaTime) override {
try {
// ์ํํ ์ ์๋ ์์
performUpdate(deltaTime);
} catch (const exception& e) {
// ์์ธ ์ฒ๋ฆฌ
cerr << "์ปดํฌ๋ํธ ์
๋ฐ์ดํธ ์คํจ: " << e.what() << endl;
// ๋ณต๊ตฌ ๋ก์ง
}
}
private:
void performUpdate(float deltaTime) {
// ์ค์ ์
๋ฐ์ดํธ ๋ก์ง
}
};
5๏ธโฃ ๋ฌธ์ํ์ ์ฃผ์
์ธํฐํ์ด์ค๋ ํนํ ์ ๋ฌธ์ํํด์ผ ํด! ๋ค๋ฅธ ๊ฐ๋ฐ์๋ค์ด ์ฌ์ฉํ ๊ฑฐ๋๊น. ๐/**
* @brief ๊ฒ์ ์ค๋ธ์ ํธ์ ๊ธฐ๋ณธ ์ปดํฌ๋ํธ ์ธํฐํ์ด์ค
*
* ๋ชจ๋ ์ปดํฌ๋ํธ๋ ์ด ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํด์ผ ํฉ๋๋ค.
* ๊ฐ ํ๋ ์๋ง๋ค update() ๋ฉ์๋๊ฐ ํธ์ถ๋ฉ๋๋ค.
*/
class Component {
public:
virtual ~Component() {}
/**
* @brief ์ปดํฌ๋ํธ ์
๋ฐ์ดํธ
* @param deltaTime ์ด์ ํ๋ ์์ผ๋ก๋ถํฐ ๊ฒฝ๊ณผํ ์๊ฐ (์ด ๋จ์)
*
* ์ด ๋ฉ์๋๋ ๋งค ํ๋ ์๋ง๋ค ํธ์ถ๋๋ฏ๋ก ์ฑ๋ฅ์ ์ฃผ์ํด์ผ ํฉ๋๋ค.
*/
virtual void update(float deltaTime) = 0;
/**
* @brief ์ปดํฌ๋ํธ ํ์
๋ฐํ
* @return ์ปดํฌ๋ํธ์ ํ์
๋ฌธ์์ด
*/
virtual string getType() const = 0;
};
๐ ํ์ต ๋ก๋๋งต๊ณผ ์ถ์ฒ ์๋ฃ
๐ ๋จ๊ณ๋ณ ํ์ต ๋ก๋๋งต
1๋จ๊ณ: ๊ธฐ์ด ๋ค์ง๊ธฐ (1-2๊ฐ์)โ C++ ๊ธฐ๋ณธ ๋ฌธ๋ฒ ์๋ฒฝ ์ดํด
โ ํด๋์ค์ ๊ฐ์ฒด ๊ฐ๋
โ ์์๊ณผ ๋คํ์ฑ ๊ธฐ์ด
โ ํฌ์ธํฐ์ ์ฐธ์กฐ ๋ง์คํฐ
2๋จ๊ณ: ๊ฐ์ฒด์งํฅ ์ฌํ (2-3๊ฐ์)
โ ๊ฐ์ํจ์์ ์์ ๊ฐ์ํจ์
โ ์ถ์ํด๋์ค์ ์ธํฐํ์ด์ค
โ ์ฐ์ฐ์ ์ค๋ฒ๋ก๋ฉ
โ ํ ํ๋ฆฟ ํ๋ก๊ทธ๋๋ฐ
3๋จ๊ณ: ๋์์ธ ํจํด (2-3๊ฐ์)
โ GoF ๋์์ธ ํจํด 23๊ฐ์ง ํ์ต
โ ์ค์ ํ๋ก์ ํธ์ ์ ์ฉ
โ ๋ฆฌํฉํ ๋ง ์ฐ์ต
โ ์ฝ๋ ๋ฆฌ๋ทฐ ์ฐธ์ฌ
4๋จ๊ณ: ์ค๋ฌด ํ๋ก์ ํธ (๊ณ์)
โ ์คํ์์ค ํ๋ก์ ํธ ๊ธฐ์ฌ
โ ๊ฐ์ธ ํ๋ก์ ํธ ์งํ
โ ์ฝ๋ ํ์ง ๊ฐ์
โ ์ฑ๋ฅ ์ต์ ํ
1๏ธโฃ ๊ฐ๋จํ ๊ฒ์ ์์ง: 2D ๊ฒ์ ์์ง์ ๋ง๋ค์ด๋ณด์
2๏ธโฃ ๊ทธ๋ํฝ ์๋ํฐ: ๋ํ ๊ทธ๋ฆฌ๊ธฐ ํ๋ก๊ทธ๋จ
3๏ธโฃ ์ฑํ ์๋ฒ: ๋คํธ์ํฌ ํ๋ก๊ทธ๋๋ฐ + ๋์์ธ ํจํด
4๏ธโฃ ๋ฐ์ดํฐ๋ฒ ์ด์ค ORM: ๊ฐ์ฒด-๊ด๊ณ ๋งคํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
5๏ธโฃ ํ๋ฌ๊ทธ์ธ ์์คํ : ํ์ฅ ๊ฐ๋ฅํ ์ ํ๋ฆฌ์ผ์ด์
์ด๋ฐ ํ๋ก์ ํธ๋ค์ ์ฌ๋ฅ๋ท์์ ํฌํธํด๋ฆฌ์ค๋ก ๊ณต์ ํ๋ฉด ์ ๋ง ์ข์! ๐
๐ป ์ถ์ฒ ํ์ต ์๋ฃ
๐ ํ๋ ์์ โข "Effective C++" - Scott Meyers
โข "Design Patterns" - GoF
โข "Clean Code" - Robert C. Martin
โข "C++ Primer" - Stanley Lippman
๐ ์จ๋ผ์ธ ๋ฆฌ์์ค
โข cppreference.com - C++ ๋ ํผ๋ฐ์ค
โข learncpp.com - ์ฒด๊ณ์ ์ธ C++ ํํ ๋ฆฌ์ผ
โข GitHub - ์คํ์์ค ํ๋ก์ ํธ ๋ถ์
โข Stack Overflow - ๋ฌธ์ ํด๊ฒฐ
๐ฎ ์ค์ต ํ๋ซํผ
โข LeetCode - ์๊ณ ๋ฆฌ์ฆ ๋ฌธ์
โข HackerRank - C++ ์ฑ๋ฆฐ์ง
โข Codewars - ์ฝ๋ฉ ์ฐ์ต
โข ์ฌ๋ฅ๋ท - ํ๋ก์ ํธ ๊ณต์ ๋ฐ ํผ๋๋ฐฑ!
๐ฅ ํํ ์ค์์ ํด๊ฒฐ ๋ฐฉ๋ฒ
โ ์ค์ 1: ๊ฐ์ ์๋ฉธ์ ๋นผ๋จน๊ธฐ
// ๋ฌธ์ ์ฝ๋
class Base {
public:
~Base() { cout << "Base ์๋ฉธ" << endl; } // virtual ์์!
};
class Derived : public Base {
private:
int* data;
public:
Derived() { data = new int[1000]; }
~Derived() {
delete[] data; // ์ด๊ฒ ํธ์ถ ์ ๋จ!
cout << "Derived ์๋ฉธ" << endl;
}
};
Base* ptr = new Derived();
delete ptr; // ๋ฉ๋ชจ๋ฆฌ ๋์ ๋ฐ์! ๐ฅ
// ํด๊ฒฐ์ฑ
class Base {
public:
virtual ~Base() { cout << "Base ์๋ฉธ" << endl; } // virtual ์ถ๊ฐ!
};
โ ์ค์ 2: ์ฌ๋ผ์ด์ฑ ๋ฌธ์
// ๋ฌธ์ ์ฝ๋
class Animal {
public:
virtual void speak() { cout << "๋๋ฌผ ์๋ฆฌ" << endl; }
};
class Dog : public Animal {
public:
void speak() override { cout << "๋ฉ๋ฉ!" << endl; }
};
void makeSound(Animal animal) { // ๊ฐ์ผ๋ก ์ ๋ฌ! ์ํ!
animal.speak();
}
Dog dog;
makeSound(dog); // "๋๋ฌผ ์๋ฆฌ" ์ถ๋ ฅ (์ฌ๋ผ์ด์ฑ ๋ฐ์!)
// ํด๊ฒฐ์ฑ
: ํฌ์ธํฐ๋ ์ฐธ์กฐ ์ฌ์ฉ
void makeSound(Animal& animal) { // ์ฐธ์กฐ๋ก ์ ๋ฌ!
animal.speak();
}
makeSound(dog); // "๋ฉ๋ฉ!" ์ถ๋ ฅ โ
โ ์ค์ 3: ์์ ๊ฐ์ํจ์ ๋ฏธ๊ตฌํ
// ๋ฌธ์ ์ฝ๋
class Shape {
public:
virtual double getArea() const = 0;
virtual void draw() const = 0;
};
class Circle : public Shape {
public:
double getArea() const override { return 3.14 * r * r; }
// draw()๋ฅผ ๊ตฌํ ์ ํจ!
};
Circle c; // ์ปดํ์ผ ์๋ฌ! ์ถ์ํด๋์ค๋ ์ธ์คํด์คํ ๋ถ๊ฐ
// ํด๊ฒฐ์ฑ
: ๋ชจ๋ ์์ ๊ฐ์ํจ์ ๊ตฌํ
class Circle : public Shape {
public:
double getArea() const override { return 3.14 * r * r; }
void draw() const override { cout << "์ ๊ทธ๋ฆฌ๊ธฐ" << endl; } // ๊ตฌํ!
};
โ ์ค์ 4: ๋ค์ค ์์ ๋ค์ด์๋ชฌ๋ ๋ฌธ์
// ๋ฌธ์ ์ฝ๋
class A {
public:
int value;
};
class B : public A { };
class C : public A { };
class D : public B, public C { }; // ๋ค์ด์๋ชฌ๋ ์์!
D d;
d.value = 10; // ์ปดํ์ผ ์๋ฌ! value๊ฐ ๋ชจํธํจ
// ํด๊ฒฐ์ฑ
1: ๊ฐ์ ์์
class B : virtual public A { };
class C : virtual public A { };
class D : public B, public C { }; // ์ด์ OK!
// ํด๊ฒฐ์ฑ
2: ์ธํฐํ์ด์ค ์ฌ์ฉ (๋ ๊ถ์ฅ)
class IB {
public:
virtual void funcB() = 0;
};
class IC {
public:
virtual void funcC() = 0;
};
class D : public IB, public IC {
// ๊ฐ๊ฐ ๊ตฌํ
};
โ ์ค์ 5: override ํค์๋ ์ ์ฐ๊ธฐ
// ๋ฌธ์ ์ฝ๋
class Base {
public:
virtual void func(int x) { }
};
class Derived : public Base {
public:
void func(double x) { } // ์ค๋ฒ๋ผ์ด๋๊ฐ ์๋๋ผ ์ค๋ฒ๋ก๋!
};
Base* ptr = new Derived();
ptr->func(10); // Base::func ํธ์ถ๋จ! ๐ฑ
// ํด๊ฒฐ์ฑ
: override ํค์๋ ์ฌ์ฉ
class Derived : public Base {
public:
void func(double x) override { } // ์ปดํ์ผ ์๋ฌ ๋ฐ์! ๐
// ์ฌ๋ฐ๋ฅธ ์๊ทธ๋์ฒ๋ก ์์
void func(int x) override { } // ์ด์ OK!
};
1๏ธโฃ ํญ์ ๊ฐ์ ์๋ฉธ์๋ฅผ ์ฌ์ฉํ์
2๏ธโฃ ๋คํ์ฑ์ด ํ์ํ๋ฉด ํฌ์ธํฐ๋ ์ฐธ์กฐ๋ฅผ ์ฌ์ฉํ์
3๏ธโฃ override ํค์๋๋ก ์ค์๋ฅผ ๋ฐฉ์งํ์
4๏ธโฃ ๋ค์ค ์์์ ์ ์คํ๊ฒ, ์ธํฐํ์ด์ค๋ฅผ ์ ํธํ์
5๏ธโฃ ์ปดํ์ผ๋ฌ ๊ฒฝ๊ณ ๋ฅผ ๋ฌด์ํ์ง ๋ง์!
๐ ๋ง๋ฌด๋ฆฌํ๋ฉฐ
์ด ๋ชจ๋ ๊ฐ๋ ๋ค์ด ์ฒ์์๋ ์ด๋ ต๊ฒ ๋๊ปด์ง ์ ์์ด. ํ์ง๋ง ๊ฑฑ์ ํ์ง ๋ง! ๋๋ ์ฒ์์ ํท๊ฐ๋ ธ๊ฑฐ๋ . ์ค์ํ ๊ฑด ๊พธ์คํ ์ฐ์ตํ๊ณ , ์ค์ ํ๋ก์ ํธ์ ์ ์ฉํด๋ณด๋ ๊ฑฐ์ผ. ๐ช
- โ ๋คํ์ฑ์ C++์ ๊ฐ์ฅ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ ์ค ํ๋
- โ ๊ฐ์ํจ์๋ก ๋ฐํ์ ๋คํ์ฑ์ ๊ตฌํ
- โ ์ถ์ํด๋์ค๋ก ์ธํฐํ์ด์ค๋ฅผ ์ ์
- โ ๋์์ธ ํจํด์ ๊ฒ์ฆ๋ ํด๊ฒฐ์ฑ
- โ SOLID ์์น์ ๋ฐ๋ฅด๋ฉด ์ ์ง๋ณด์๊ฐ ์ฌ์์ง
- โ ์ค๋ฌด ๊ฒฝํ์ด ๊ฐ์ฅ ์ค์!
ํ๋ก๊ทธ๋๋ฐ์ ๊ฒฐ๊ตญ ๋ฌธ์ ํด๊ฒฐ์ด์ผ. ๊ฐ์ฒด์งํฅ๊ณผ ๋์์ธ ํจํด์ ๊ทธ ๋ฌธ์ ๋ฅผ ๋ ์ฐ์ํ๊ณ ํจ์จ์ ์ผ๋ก ํด๊ฒฐํ๋ ๋๊ตฌ์ผ ๋ฟ์ด์ผ. ๋๊ตฌ๋ฅผ ์ ๋ค๋ฃจ๋ ๊ฒ๋ ์ค์ํ์ง๋ง, ์ด๋ค ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ง, ์ ์ด ๋๊ตฌ๋ฅผ ์ฌ์ฉํ๋์ง ์ดํดํ๋ ๊ฒ ๋ ์ค์ํด! ๐ฏ
์์ผ๋ก ์ฝ๋๋ฅผ ์์ฑํ ๋ ์ด๋ ๊ฒ ์๊ฐํด๋ด:
โข "์ด ํด๋์ค๋ ํ๋์ ์ฑ ์๋ง ๊ฐ์ง๊ณ ์๋?" (SRP)
โข "์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ ๋ ๊ธฐ์กด ์ฝ๋๋ฅผ ์์ ํด์ผ ํ๋?" (OCP)
โข "์ด ํจํด์ด ์ ๋ง ํ์ํ๊ฐ, ์๋๋ฉด ๊ณผ๋ํ ์ค๊ณ์ธ๊ฐ?"
โข "๋ค๋ฅธ ๊ฐ๋ฐ์๊ฐ ์ด ์ฝ๋๋ฅผ ์ดํดํ๊ธฐ ์ฌ์ธ๊น?"
์ข์ ์ฝ๋๋ ํ๋ฃจ์์นจ์ ๋ง๋ค์ด์ง์ง ์์. ๊ณ์ ๋ฐฐ์ฐ๊ณ , ์คํํ๊ณ , ๋ฆฌํฉํ ๋งํ๋ฉด์ ์ ์ ๋์์ง๋ ๊ฑฐ์ผ. ์ค์ํด๋ ๊ด์ฐฎ์! ๊ทธ๊ฒ ๋ฐฐ์ฐ๋ ๊ณผ์ ์ด๋๊น. ๐
1๏ธโฃ ์์ ํ๋ก์ ํธ๋ถํฐ ์์ํด์ ๋ฐฐ์ด ํจํด๋ค์ ์ ์ฉํด๋ณด์
2๏ธโฃ ์คํ์์ค ํ๋ก์ ํธ์ ์ฝ๋๋ฅผ ์ฝ์ด๋ณด์ (ํนํ ๊ฒ์ ์์ง!)
3๏ธโฃ ์ฝ๋ ๋ฆฌ๋ทฐ๋ฅผ ๋ฐ๊ณ ํผ๋๋ฐฑ์ ์ ๊ทน ์์ฉํ์
4๏ธโฃ ์ฌ๋ฅ๋ท์์ ํ๋ก๊ทธ๋๋ฐ ์ฌ๋ฅ์ ๊ณต์ ํ๋ฉฐ ์ค๋ ฅ์ ํค์ฐ์
5๏ธโฃ ๊ณ์ ์๋ก์ด ๊ฒ์ ๋ฐฐ์ฐ๊ณ ๋์ ํ์!
ํ๋ณตํ ์ฝ๋ฉ ๋๊ธธ ๋ฐ๋ผ! Happy Coding! ๐ปโจ
๊ด๋ จ ํค์๋
๋๊ธ 0
์ง์์ธ์ ์ฒ - ์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
- ์ ์๊ถ ๋ฐ ์์ ๊ถ: ๋ณธ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ๋ ์ AI ๊ธฐ์ ๋ก ์์ฑ๋์์ผ๋ฉฐ, ๋ํ๋ฏผ๊ตญ ์ ์๊ถ๋ฒ ๋ฐ ๊ตญ์ ์ ์๊ถ ํ์ฝ์ ์ํด ๋ณดํธ๋ฉ๋๋ค.
- AI ์์ฑ ์ปจํ ์ธ ์ ๋ฒ์ ์ง์: ๋ณธ AI ์์ฑ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ์ง์ ์ฐฝ์๋ฌผ๋ก ์ธ์ ๋๋ฉฐ, ๊ด๋ จ ๋ฒ๊ท์ ๋ฐ๋ผ ์ ์๊ถ ๋ณดํธ๋ฅผ ๋ฐ์ต๋๋ค.
- ์ฌ์ฉ ์ ํ: ์ฌ๋ฅ๋ท์ ๋ช ์์ ์๋ฉด ๋์ ์์ด ๋ณธ ์ปจํ ์ธ ๋ฅผ ๋ณต์ , ์์ , ๋ฐฐํฌ, ๋๋ ์์ ์ ์ผ๋ก ํ์ฉํ๋ ํ์๋ ์๊ฒฉํ ๊ธ์ง๋ฉ๋๋ค.
- ๋ฐ์ดํฐ ์์ง ๊ธ์ง: ๋ณธ ์ปจํ ์ธ ์ ๋ํ ๋ฌด๋จ ์คํฌ๋ํ, ํฌ๋กค๋ง, ๋ฐ ์๋ํ๋ ๋ฐ์ดํฐ ์์ง์ ๋ฒ์ ์ ์ฌ์ ๋์์ด ๋ฉ๋๋ค.
- AI ํ์ต ์ ํ: ์ฌ๋ฅ๋ท์ AI ์์ฑ ์ปจํ ์ธ ๋ฅผ ํ AI ๋ชจ๋ธ ํ์ต์ ๋ฌด๋จ ์ฌ์ฉํ๋ ํ์๋ ๊ธ์ง๋๋ฉฐ, ์ด๋ ์ง์ ์ฌ์ฐ๊ถ ์นจํด๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.

๋๊ธ ์์ฑ
์ด ๊ธ์ ๋ํ ์ฌ๋ฌ๋ถ์ ์๊ฐ์ ๋ค๋ ค์ฃผ์ธ์
๋ก๊ทธ์ธ์ด ํ์ํฉ๋๋ค
๋๊ธ์ ์์ฑํ๋ ค๋ฉด ๋จผ์ ๋ก๊ทธ์ธํด์ฃผ์ธ์.