디자인 패턴이란?
반복적으로 등장하는 개발 문제를 해결하기 위한 일반화된 솔루션.
디자인 패턴의 분류
- 생성 패턴(Creational Patterns)
- 객체 생성과 관련된 패턴.
- 예: 싱글톤 패턴
- 구조 패턴(Structural Patterns)
- 객체 간의 관계를 구성하는 패턴.
- 예: 데코레이터 패턴
- 행동 패턴(Behavioral Patterns)
- 객체 간의 상호작용을 정의하는 패턴.
- 예: 옵저버 패턴
싱글톤 패턴 (Singleton Pattern)
목표
- 객체를 오직 하나만 생성하고 전역적으로 접근 가능하도록 함.
주요 개념
- 생성자를 private으로 설정하여 외부에서 객체 생성을 제한.
- getInstance() 메서드를 통해 유일한 인스턴스에 접근.
코드 예제
#include <iostream>
using namespace std;
class Airplane {
private:
static Airplane* instance; // 유일한 인스턴스를 가리키는 정적 포인터
int positionX; // X 좌표
int positionY; // Y 좌표
Airplane() : positionX(0), positionY(0) { // private 생성자
cout << "Airplane Created at (" << positionX << ", " << positionY << ")" << endl;
}
public:
// 복사 방지: 복사 생성자와 대입 연산자 삭제
Airplane(const Airplane&) = delete;
Airplane& operator=(const Airplane&) = delete;
// 유일한 인스턴스 반환
static Airplane* getInstance() {
if (instance == nullptr) { // 아직 생성되지 않았다면
instance = new Airplane();
}
return instance;
}
void move(int deltaX, int deltaY) {
positionX += deltaX;
positionY += deltaY;
cout << "Airplane moved to (" << positionX << ", " << positionY << ")" << endl;
}
void getPosition() const {
cout << "Airplane Position: (" << positionX << ", " << positionY << ")" << endl;
}
};
Airplane* Airplane::instance = nullptr;
int main() {
Airplane* airplane = Airplane::getInstance();
airplane->move(10, 20);
airplane->getPosition();
Airplane* sameAirplane = Airplane::getInstance();
sameAirplane->move(-5, 10);
sameAirplane->getPosition();
return 0;
}
코드 설명
- static 포인터로 유일한 객체를 관리.
- getInstance()에서 처음 호출 시 객체를 생성하고 이후에는 동일한 객체를 반환.
- 장점: 자원을 효율적으로 관리.
- 단점: 멀티스레드 환경에서는 동기화 필요.
데코레이터 패턴 (Decorator Pattern)
목표
- 객체의 기능을 동적으로 확장하거나 변경할 수 있도록 함.
주요 개념
- 기본 컴포넌트: 핵심 기능을 가진 클래스.
- 데코레이터 클래스: 기존 객체를 감싸 추가 기능을 제공.
코드 예제
#include <iostream>
#include <string>
using namespace std;
// 기본 피자 클래스
class Pizza {
public:
virtual ~Pizza() {}
virtual string getName() const = 0;
virtual double getPrice() const = 0;
};
class BasicPizza : public Pizza {
public:
string getName() const { return "Basic Pizza"; }
double getPrice() const { return 5.0; }
};
class PizzaDecorator : public Pizza {
protected:
Pizza* pizza;
public:
PizzaDecorator(Pizza* p) : pizza(p) {}
virtual ~PizzaDecorator() { delete pizza; }
};
class CheeseDecorator : public PizzaDecorator {
public:
CheeseDecorator(Pizza* p) : PizzaDecorator(p) {}
string getName() const { return pizza->getName() + " + Cheese"; }
double getPrice() const { return pizza->getPrice() + 1.5; }
};
class PepperoniDecorator : public PizzaDecorator {
public:
PepperoniDecorator(Pizza* p) : PizzaDecorator(p) {}
string getName() const { return pizza->getName() + " + Pepperoni"; }
double getPrice() const { return pizza->getPrice() + 2.0; }
};
int main() {
Pizza* pizza = new BasicPizza();
pizza = new CheeseDecorator(pizza);
pizza = new PepperoniDecorator(pizza);
cout << "Pizza: " << pizza->getName() << endl;
cout << "Price: $" << pizza->getPrice() << endl;
delete pizza;
return 0;
}
코드 설명
- PizzaDecorator가 Pizza 객체를 감싸 동적으로 기능 추가.
- 장점: 기존 코드를 수정하지 않고도 기능 확장 가능.
옵저버 패턴 (Observer Pattern)
목표
- 객체 상태가 변경되면, 이를 관찰하는 다른 객체들에게 자동으로 알림.
주요 개념
- Subject: 상태를 관리하며, 관찰자를 등록 및 관리.
- Observer: Subject의 상태 변경을 감지.
코드 예제
#include <iostream>
#include <vector>
using namespace std;
class Observer {
public:
virtual void update(int data) = 0;
};
class ExcelSheet {
private:
vector<Observer*> observers;
int data;
public:
void attach(Observer* observer) {
observers.push_back(observer);
}
void setData(int newData) {
data = newData;
for (Observer* obs : observers) obs->update(data);
}
};
class BarChart : public Observer {
public:
void update(int data) {
cout << "BarChart updated with data: " << data << endl;
}
};
int main() {
ExcelSheet sheet;
BarChart barChart;
sheet.attach(&barChart);
sheet.setData(5);
return 0;
}
코드 설명
- ExcelSheet에서 데이터 변경 시 모든 Observer가 알림을 받음.
- 장점: 느슨한 결합으로 객체 간 관계 관리.
'TIL > C++' 카테고리의 다른 글
Unreal Engine에서 Tick 사용법 (0) | 2025.01.08 |
---|---|
챕터 3-2: Unreal Engine 기본 개념 (2) | 2025.01.07 |
챕터 2-4: 객체지향적 설계 (1) | 2025.01.03 |
챕터 2-3 : STL 기초 (1) | 2025.01.02 |
챕터 2-2 : 템플릿 (1) | 2024.12.31 |