상위 클래스가 제공하는 기능들을 통해서 하위 클래스에서 행동을 정의한다.
상위 클래스는 추상 샌드박스 메서드와 여러 제공 기능을 정의한다. 제공 기능은 protected로 만들어져 하위 클래스용이라는 걸 분명히 한다. 각 하위 클래스는 제공 기능을 이용해 샌드박스 메서드를 구현한다.
커플링이 복잡하게 되어 있으면 상위 클래스를 조금만 바꿔도 어딘가가 깨지기 쉽다.
#include <iostream>
using namespace std;
class SoundPlayer {
public:
void PlaySound(SoundId sound, double volume) {
soundEngine_.play(sound, volume);
}
void StopSound(SoundId sound) {
//생략
}
void SetVolume(SoundId sound) {
//생략
}
};
class Superpower {
public:
virtual ~Superpower() {}
protected:
//하위 클래스에서 구현해야 하는 내용을 순수 가상 메서드로 만든다.
virtual void Activate() = 0;
void Move(double x, double y, double z) {
//생략
}
void SpawnParticles(ParticleType type, int count) {
// 서비스 중개자 패턴 이용
ParticleSystem& particles = Locator::getParticles();
particles.spawn(type, count);
}
void PlaySound(SoundID soundid, int volume) {
// 서비스 중개자 패턴 이용
SoundSystem& sound = Locator::getSound();
sound.play(soundid, volume);
}
double getHeroX() { return x; }
double getHeroY() { return y; }
double getHeroZ() { return z; }
private:
double x, y, z;
};
class SkyLaunch : public Superpower {
protected:
virtual void activate() {
if (getHeroZ() == 0) {
// 땅이라면 공중으로 뛴다.
PlaySound(SOUND_SPROING, 1.0f);
SpawnParticles(PARTICLE_DUST, 10);
Move(0, 0, 20);
}
else if (getHeroZ() < 10.0f) {
// 거의 땅에 도착했다면 이중 점프를 한다.
PlaySound(SOUND_SWOOP, 1.0f);
Move(0, 0, GetHeroZ() - 20);
}
else {
// 공중에 높이 떠 있다면 내려찍기 공격을 한다.
PlaySound(SOUND_DIVE, 0.7f);
SpawnParticles(PARTICLE_SPARKLES, 1);
move(0, 0, -getHeroZ());
}
}
};