[게임 프로그래밍 패턴] 15. 서비스 중개자 패턴

WIGWAG·2023년 3월 18일

서비스를 구현한 구체 클래스는 숨긴 채로 어디에서나 서비스에 접근할 수 있게 한다.

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);
}
profile
프로그래밍 공부 기록 노트

0개의 댓글