C++ Facade 패턴
복잡한 서브시스템에 단순화된 인터페이스를 제공합니다. 멀티미디어 시스템처럼 여러 복잡한 내부 모듈을 하나의 퍼사드로 감싸 사용자가 쉽게 접근할 수 있게 합니다.
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <stdexcept>
// ──────────────────────────────────────────────
// 서브시스템 클래스들: 각각 복잡한 내부 로직 보유
// 클라이언트는 이 클래스들을 직접 다루지 않아도 됨
// ──────────────────────────────────────────────
class AudioDecoder {
public:
void loadCodec(const std::string& format) {
std::cout << " [AudioDecoder] " << format << " 코덱 로드 완료\n";
}
void setVolume(int level) {
std::cout << " [AudioDecoder] 볼륨 설정: " << level << "%\n";
}
void decode(const std::string& file) {
std::cout << " [AudioDecoder] 오디오 디코딩 중: " << file << "\n";
}
void release() {
std::cout << " [AudioDecoder] 코덱 자원 해제\n";
}
};
class VideoDecoder {
public:
void initialize(int width, int height) {
std::cout << " [VideoDecoder] 해상도 초기화: "
<< width << "x" << height << "\n";
}
void loadCodec(const std::string& format) {
std::cout << " [VideoDecoder] " << format << " 코덱 로드 완료\n";
}
void decode(const std::string& file) {
std::cout << " [VideoDecoder] 비디오 디코딩 중: " << file << "\n";
}
void release() {
std::cout << " [VideoDecoder] 코덱 자원 해제\n";
}
};
class DisplayManager {
public:
void setResolution(int width, int height) {
std::cout << " [DisplayManager] 디스플레이 해상도: "
<< width << "x" << height << "\n";
}
void setFullscreen(bool enabled) {
std::cout << " [DisplayManager] 전체화면: "
<< (enabled ? "활성화" : "비활성화") << "\n";
}
void render() {
std::cout << " [DisplayManager] 프레임 렌더링 중...\n";
}
void close() {
std::cout << " [DisplayManager] 디스플레이 종료\n";
}
};
class NetworkStream {
public:
bool connect(const std::string& url) {
std::cout << " [NetworkStream] 스트림 연결: " << url << "\n";
return true; // 실제에선 연결 실패 처리 필요
}
std::string fetchMetadata() {
return R"({"title":"샘플 영상","format":"mp4","bitrate":"4Mbps"})";
}
void disconnect() {
std::cout << " [NetworkStream] 스트림 연결 해제\n";
}
};
class SubtitleEngine {
public:
void loadSubtitle(const std::string& lang) {
std::cout << " [SubtitleEngine] 자막 로드: " << lang << "\n";
}
void render(int timestamp) {
std::cout << " [SubtitleEngine] 자막 렌더링 (t=" << timestamp << "ms)\n";
}
void unload() {
std::cout << " [SubtitleEngine] 자막 언로드\n";
}
};
// ──────────────────────────────────────────────
// 퍼사드: 복잡한 멀티미디어 서브시스템을 단순한 API로 노출
// ──────────────────────────────────────────────
class MediaPlayerFacade {
public:
MediaPlayerFacade()
: audio_(std::make_unique<AudioDecoder>())
, video_(std::make_unique<VideoDecoder>())
, display_(std::make_unique<DisplayManager>())
, network_(std::make_unique<NetworkStream>())
, subtitle_(std::make_unique<SubtitleEngine>()) {}
// 온라인 스트리밍 재생 (복잡한 초기화 과정을 하나의 메서드로)
void playStream(const std::string& url, const std::string& subtitleLang = "ko") {
std::cout << "\n[MediaPlayerFacade] 스트림 재생 시작: " << url << "\n";
// 1. 네트워크 연결 및 메타데이터 획득
if (!network_->connect(url)) {
throw std::runtime_error("스트림 연결 실패: " + url);
}
const auto meta = network_->fetchMetadata();
std::cout << " [MediaPlayerFacade] 메타데이터: " << meta << "\n";
// 2. 디코더 초기화
video_->initialize(1920, 1080);
video_->loadCodec("H.264");
audio_->loadCodec("AAC");
audio_->setVolume(80);
// 3. 디스플레이 설정
display_->setResolution(1920, 1080);
display_->setFullscreen(true);
// 4. 자막 로드
subtitle_->loadSubtitle(subtitleLang);
// 5. 재생
video_->decode(url);
audio_->decode(url);
display_->render();
subtitle_->render(0);
std::cout << "[MediaPlayerFacade] ▶ 재생 중...\n";
}
// 로컬 파일 재생
void playFile(const std::string& filePath) {
std::cout << "\n[MediaPlayerFacade] 로컬 파일 재생: " << filePath << "\n";
video_->initialize(1280, 720);
video_->loadCodec("H.265");
audio_->loadCodec("MP3");
audio_->setVolume(70);
display_->setResolution(1280, 720);
display_->setFullscreen(false);
video_->decode(filePath);
audio_->decode(filePath);
display_->render();
std::cout << "[MediaPlayerFacade] ▶ 재생 중...\n";
}
// 재생 중단 및 자원 정리
void stop() {
std::cout << "\n[MediaPlayerFacade] 재생 중단 및 자원 정리\n";
subtitle_->unload();
audio_->release();
video_->release();
display_->close();
network_->disconnect();
std::cout << "[MediaPlayerFacade] ■ 정지 완료\n";
}
private:
std::unique_ptr<AudioDecoder> audio_;
std::unique_ptr<VideoDecoder> video_;
std::unique_ptr<DisplayManager> display_;
std::unique_ptr<NetworkStream> network_;
std::unique_ptr<SubtitleEngine> subtitle_;
};
// ──────────────────────────────────────────────
// 사용 예시
// ──────────────────────────────────────────────
int main() {
std::cout << "=== 멀티미디어 플레이어 (Facade 패턴) ===\n";
MediaPlayerFacade player;
// 클라이언트는 복잡한 서브시스템 세부사항을 알 필요 없음
player.playStream("https://cdn.example.com/video/sample.mp4", "ko");
player.stop();
std::cout << "\n--- 로컬 파일 재생 ---";
MediaPlayerFacade localPlayer;
localPlayer.playFile("/videos/movie.mkv");
localPlayer.stop();
return 0;
}