서비스를 구현한 구체 클래스는 숨긴 채로 어디에서나 서비스에 접근할 수 있게 한다.
class Audio {
public:
virtual ~Audio() {}
virtual void PlaySound(int soundId) = 0;
virtual void StopSound(int soundId) = 0;
virtual void StopAllSounds() = 0;
};
class ConsoleAudio : public Audio {
public:
virtual void PlaySound(int soundId) {
// 콘솔의 오디오 API를 이용해 사운드를 출력한다...
}
virtual void StopSound(int soundId) {
// 콘솔의 오디오 API를 이용해 사운드를 중지한다...
}
virtual void StopAllSounds() {
// 콘솔의 오디오 API를 이용해 모든 사운드를 중지한다...
}
};
class NullAudio : public Audio {
//아무것도 하지 않는다.
virtual void PlaySound(int soundId) {}
virtual void StopSound(int soundId) {}
virtual void StopAllSounds() {}
};
class LoggedAudio : public Audio {
public:
LoggedAudio(Audio& wrapped) : wrapped_(wrapped) {}
virtual void PlaySound(int soundId) {
log("사운드 출력");
wrapped_.PlaySound(soundId);
}
virtual void StopSound(int soundId) {
log("사운드 중지");
wrapped_.StopSound(soundId);
}
virtual void StopAllSounds() {
log("모든 사운드 중지");
wrapped_.StopAllSounds();
}
private:
void log(const char* message) {
// 로그를 남기는 코드
}
Audio& wrapped_;
};
class Locator {
public:
static void initialize() {
service_ = &nullService_;
}
static Audio& GetAudio() { return *service_; }
static void Provide(Audio* service) {
if (service == nullptr) {
//널 서비스로 돌려놓는다.
service_ = &nullService_;
}
else {
service_ = service;
}
}
private:
static Audio* service_;
static NullAudio nullService_;
};
int main() {
Locator::initialize();
ConsoleAudio* con_audio = new ConsoleAudio();
//등록
Locator::Provide(con_audio);
//어디서나 사용
Audio *audio = Locator::GetAudio();
audio->PlaySound(166);
Audio* service = new LoggedAudio(Locator::GetAudio());
Locator::Provide(service);
}