C++ Factory Method 패턴
추상 Creator가 객체 생성 인터페이스를 정의하고, 서브클래스가 구체적인 객체를 생성하는 Factory Method 패턴입니다. 알림(Notification) 발송 시스템을 예시로 구현합니다.
#include <iostream>
#include <memory>
#include <string>
#include <vector>
// ─────────────────────────────────────────────
// Product 인터페이스: 모든 알림 채널의 공통 계약
// ─────────────────────────────────────────────
class Notification {
public:
virtual ~Notification() = default;
virtual void send(const std::string& recipient,
const std::string& message) const = 0;
virtual std::string channelName() const = 0;
};
// ─────────────────────────────────────────────
// ConcreteProduct: 이메일 알림
// ─────────────────────────────────────────────
class EmailNotification final : public Notification {
public:
void send(const std::string& recipient,
const std::string& message) const override {
std::cout << "[EMAIL] → " << recipient
<< " : " << message << "\n";
}
std::string channelName() const override { return "Email"; }
};
// ─────────────────────────────────────────────
// ConcreteProduct: SMS 알림
// ─────────────────────────────────────────────
class SmsNotification final : public Notification {
public:
void send(const std::string& recipient,
const std::string& message) const override {
std::cout << "[SMS] → " << recipient
<< " : " << message << "\n";
}
std::string channelName() const override { return "SMS"; }
};
// ─────────────────────────────────────────────
// ConcreteProduct: 슬랙 알림
// ─────────────────────────────────────────────
class SlackNotification final : public Notification {
public:
void send(const std::string& recipient,
const std::string& message) const override {
std::cout << "[SLACK] → #" << recipient
<< " : " << message << "\n";
}
std::string channelName() const override { return "Slack"; }
};
// ─────────────────────────────────────────────
// Creator 인터페이스: 팩토리 메서드를 선언
// 공통 비즈니스 로직은 여기에 구현
// ─────────────────────────────────────────────
class NotificationSender {
public:
virtual ~NotificationSender() = default;
// 팩토리 메서드 — 서브클래스가 반드시 구현
virtual std::unique_ptr<Notification> createNotification() const = 0;
// 공통 로직: 채널 정보 출력 후 발송
void notify(const std::string& recipient,
const std::string& message) const {
auto notif = createNotification();
std::cout << "[" << notif->channelName() << " 채널 사용] ";
notif->send(recipient, message);
}
// 벌크 발송: 여러 수신자에게 동일 메시지 전달
void broadcastAll(const std::vector<std::string>& recipients,
const std::string& message) const {
for (const auto& r : recipients) {
notify(r, message);
}
}
};
// ─────────────────────────────────────────────
// ConcreteCreator: 각 채널별 발송자 구현
// ─────────────────────────────────────────────
class EmailSender final : public NotificationSender {
public:
std::unique_ptr<Notification> createNotification() const override {
return std::make_unique<EmailNotification>();
}
};
class SmsSender final : public NotificationSender {
public:
std::unique_ptr<Notification> createNotification() const override {
return std::make_unique<SmsNotification>();
}
};
class SlackSender final : public NotificationSender {
public:
std::unique_ptr<Notification> createNotification() const override {
return std::make_unique<SlackNotification>();
}
};
// ─────────────────────────────────────────────
// 사용 예시
// ─────────────────────────────────────────────
int main() {
// 각 Creator를 다형적으로 사용
std::vector<std::unique_ptr<NotificationSender>> senders;
senders.push_back(std::make_unique<EmailSender>());
senders.push_back(std::make_unique<SmsSender>());
senders.push_back(std::make_unique<SlackSender>());
// 단일 발송
for (const auto& sender : senders) {
sender->notify("admin@example.com", "서버 배포 완료");
}
std::cout << "\n--- 브로드캐스트 ---\n";
// 벌크 발송: Creator 인터페이스만 알면 됨 (구체 타입 불필요)
std::vector<std::string> recipients = {"user1", "user2", "user3"};
senders[2]->broadcastAll(recipients, "시스템 점검 예정 안내");
return 0;
}