{ ๋ช ๋ น ํจํด์ด๋? }
๋ช ๋ น ํจํด์ GoF์ ํ์ ํจํด ์ค ํ๋๋ก,
์์ฒญ(๋ช ๋ น)์ ๊ฐ์ฒด์ ํํ๋ก ์บก์ํํ์ฌ ์ฌ์ด์ฉํ๊ฑฐ๋ ์ทจ์ํ ์ ์๋๋ก ์์ฒญ์ ํ์ํ ์ ๋ณด๋ฅผ ์ ์ฅํ๊ฑฐ๋ ๋ก๊ทธ์ ๋จ๊ธฐ๋ ํจํด์ด๋ค.
๋ ๊ฐ๋จํ๊ฒ ๋ฉ์๋ ํธ์ถ์ ๊ฐ์ฒด๋ก ๊ฐ์ผ ํํ์ด๋ค.
์ฝ๋ฐฑ์ ๊ฐ์ฒด ์งํฅ์ ์ผ๋ก ์ค๊ณํ๋ค๊ณ ์๊ฐํ๋ฉด ์ข๋ค.
์์ฒญ์ ์ฌ์ฉ๋๋ ๊ฐ์ข ๋ช ๋ น์ด๋ค์ ์ถ์ ํด๋์ค์ ๊ตฌ์ฒด ํด๋์ค๋ก ๋ถ๋ฆฌํ์ฌ ๋จ์ํํ๋ค.
{ ๊ฒ์ ๊ฐ๋ฐ์์ ๋ช ๋ น ํจํด ํ์ฉํ๊ธฐ : ์บ๋ฆญํฐ ์กฐ์ }
๊ฒ์ ๊ฐ๋ฐ์ ๋ค์ํ ๋ถ๋ถ์์ ๋ช ๋ น ํจํด์ ํ์ฉํ ์ ์๊ฒ ์ง๋ง,
'๋ช ๋ น' ํ๋ฉด ๊ฐ์ฅ ๋จผ์ ์๊ฐ๋๋ ์ปจํธ๋กค๋ฌ์ ์ ๋ ฅ(๋ช ๋ น)์ ๋ฐ๋ผ ํ๋ ์ด์ด๋ฅผ ์์ง์ด๋ ๋ก์ง์ ๋ช ๋ น ํจํด์ผ๋ก ๊ตฌํํด๋ณด์.
๋ช ๋ น ํจํด์ ์ ์ฉํ๊ธฐ ์ ์ฝ๋
void CInputHandler::HandleInput()
{
if(isPressed(KEY::SPACE)) CPlayer::Jump();
else if(isPressed(KEY::E)) CPlayer::UseSkill();
else if(isPressed(KEY::CTRL)) CPlayer::Crouch();
}
์ ์ฝ๋๋ ํน์ ํค๋ฅผ ๋๋ฅด๋ฉด ํ๋์ด์ด ์บ๋ฆญํฐ๊ฐ ์ ์ ํ ๋์์ ํ๋ ์ฝ๋์ด๋ค.
์ด ์ฝ๋๋ฅผ ์ดํดํ๊ธฐ๋ ์ฝ์ง๋ง ๋จ์ ์ด ์๋ค.
์ฐ์ key ๋ณ๊ฒฝ์ด ๋ถ๊ฐ๋ฅํ๋ค.
๋ํ ํ๋ ์ด์ด์ ํน์ ๋์์๋ง ๋ฐ์ธ๋ฉ์ด ๋์ด ๋ฒ์ฉ์ ์ด์ง ๋ชปํ๋ค.
์ด ์ฝ๋๋ฅผ ๋ช ๋ น ํจํด์ ์ฌ์ฉํ์ฌ ์กฐ๊ธ ๋ ์ ์ฐํ๊ณ ๋ฒ์ฉ์ ์ธ ์ฝ๋๋ก ๋ง๋ค์ด๋ณด์.
๋ช ๋ น ํจํด์ ์ ์ฉํ์
1. ๋ช ๋ น๋ค์ ๊ณตํต ์์ ์ถ์ ํด๋์ค๋ฅผ ๋ง๋ ๋ค.
class Command
{
public:
virtual ~Command();
virtual void execute() = 0;
}
- Command๋ผ๋ ๊ฐ์ฒด๋ก execute()๋ผ๋ ๋ช ๋ น์ ๊ฐ์ผ ํํ์ด๋ค.
- ๊ธฐ๋ฐ ํด๋์ค์ ์๋ฉธ์์ virtual ํค์๋๋ฅผ ๋ถ์ด๋ ๊ฒ์ ์์ง ๋ง์.
2. ํ๋ ๋ณ๋ก ๊ตฌ์ฒด ํด๋์ค๋ฅผ ๋ง๋ ๋ค.
class CJumpCommand : public Command
{
public:
virtual void execute() { CPlayer::Jump(); }
};
class CUseSkillCommand : public Command
{
public:
virtual void execute() { CPlayer::UseSkill(); }
};
class CCrouchCommand : public Command
{
public:
virtual void execute() { CPlayer::Crouch(); }
};
3. InputHandler์ ๊ฐ ๋ฒํผ ๋ณ๋ก ๋ฐ์ธ๋ ๋ Command ํด๋์ค ํฌ์ธํฐ๋ฅผ ์ ์ฅํ๋ค.
- ์ ๋ ฅ์ ๋ฐ๋ผ ์ ์ ํ ๋ฒํผ์ Command->execute()ํจ์๋ฅผ ํธ์ถํด์ฃผ๋ฉด ๋๋ค.
class CInputHandler
{
public:
void HandleInput();
private:
Command* m_btn_space_command;
Command* m_btn_e_command;
Command* m_btn_ctrl_command;
}
void CInputHandler::HandleInput
{
if(isPressed(KEY::SPACE)) m_btn_space_command->execute();
else if(isPressed(KEY::E)) m_btn_e_command->execute();
else if(isPressed(KEY::CTRL)) m_btn_ctrl_command->execute();
}
๋ ๊ฐ์ ํ ์ ์์๊น?
๋ช ๋ น ํจํด์ ํ์ฉํด์ InputHandler์ Player์ ์ปคํ๋ง์ ํด์ํ๋ค.
์ด์ ๋์์ ๋ฐ๋ผ key ๋ณ๊ฒฝ์ด ๊ฐ๋ฅํ๋ค.
๋ํ ์ด๋ ๋์์ด๋ ์ง key์ ๋ฐ์ธ๋ฉํ์ฌ ํธ์ถํ ์ ์๋ค.
์ค๋ น ๊ทธ ๋์์ด Player์ ๊ด๋ จ๋ ๋์์ด ์๋์ด๋ ๊ด์ฐฎ๋ค.
๊ทธ๋ฌ๋ ์ฌ์ ํ ํ๊ณ์ ์ ์๋ค.
JumpCommand์ ๊ฐ์ Command๋ค์ Player์๋ง ํ์ ๋์ด์๋ค.
๋ฐ๋ผ์ ๊ฐ์ ์ข ๋ฅ์ ์์ง์์ ๋ช ๋ นํ๋ Command๋ผ๋ ํด๋์ค ๋ณ๋ก ๋ฐ๋ก ๋ง๋ค์ด์ค์ผ ํ๋ค.
์๋ฅผ ๋ค์ด Monter์ Jump Command๋ฅผ ๋ง๋ ๋ค๊ณ ํ๋ฉด,
Monster1JumpCommand,Monster2JumnpCommand, ... ์ฒ๋ผ
๋ชฌ์คํฐ ์ข ๋ฅ ๋ณ๋ก ๋ณ๋์ JumpCommand ํด๋์ค๋ฅผ ์์ฑํด์ค์ผ ํ๋ค.
๋ง์ฝ ์ด๋ฐ Command๋ค์ด Player์ ๊ฐ์ ํน์ ํด๋์ค์ ํ์ ๋์ด์์ง ์๊ณ
๋ชจ๋ ์์ง์ผ ์ ์๋ ํด๋์ค(Actor)๋ค์๊ฒ ๊ณตํต์ผ๋ก ์ ์ฉ๋ ์ ์๋ค๋ฉด ๋ ๋ฒ์ฉ์ฑ์ด ์ข์ง ์์๊น?
Command ๊ฐ์ ํ๊ธฐ
1. Command์ ๋์ ์ฃผ์ฒด๋ฅผ ์ธ๋ถ์์ ์ค์ ํ ์ ์๊ฒ ํ๋ค.
class Command
{
public:
virtual ~Command() {};
virtual void execute(GameActor& actor) = 0;
}
2. Command๋ฅผ ์์๋ฐ์ ํด๋์ค๋ค์ด actor๋ฅผ ํ์ฉํ๋๋ก ์์ ํ๋ค.
class CJumpCommand : public Command
{
public:
//virtual void execute() { CPlayer::Jump(); }
virtual void execute(GameActor& _actor)
{
_actor.Jump();
}
};
class CUseSkillCommand : public Command
{
public:
//virtual void execute() { CPlayer::UseSkill(); }
virtual void execute(GameActor& _actor)
{
_actor.UseSkill();
}
};
class CCrouchCommand : public Command
{
public:
//virtual void execute() { CPlayer::Crouch(); }
virtual void execute(GameActor& _actor)
{
_actor.Crouch();
}
};
3. CInputHandler์์ ๋ฒํผ์ด ๋๋ฆฌ๋ฉด Command๋ฅผ ๋ฐํํ๋๋ก ์์ ํ๋ค.
// Command.cpp
Command* CInputHandler::handleInput()
{
if(isPressed(KEY::SPACE)) return m_btn_space_command;
else if(isPressed(KEY::E)) return m_btn_e_command;
else if(isPressed(KEY::CTRL)) return m_btn_ctrl_command;
else return nullptr;
}
4. ๋ฐํ๋ Command๋ GameActor๊ฐ ๋ฐ์, GameActor์ ๋ฑ๋กํด ๋ Actor๋ฅผ ์ธ์๋ก ๋ฃ์ด Command์ execute()๋ฅผ ์คํํ๋ค.
// CGameActor.cpp
// CGameActor๋ ๋ฉค๋ฒ ๋ณ์๋ก static CGameActor* m_actor ์์ .
void CGameActor::ControlActor()
{
Command* c = CInputHandler::handleInput();
if(c)
{
c->execute(m_actor);
}
}
์ด๋ ๊ฒ ๊ตฌํํ๋ฉด ๋ชจ๋ GameActor๋ฅผ ์์๋ฐ๋ ๊ฐ์ฒด๋ค์ ์ปจํธ๋กค๋ฌ๋ก ์กฐ์ข ํ ์ ์๊ฒ ๋๋ค.
{ ๋ช ๋ น ์คํ ์ทจ์์ ์ฌ์คํ }
๋ช ๋ น ํจํด์ ํ์ฉํ๋ฉด ๋ช ๋ น ์คํ ์ทจ์์ ์ฌ์คํ์ด ๊ฐ๋ฅํ๋ค.
๋ช ๋ น ์คํ ์ทจ์
์ฐ์ Command์ undo()ํจ์๋ฅผ ์ถ๊ฐํ๋ค.
Command๋ execute()๊ฐ ํธ์ถ๋๋ฉด ํ์ฌ ์ํ๋ฅผ ์ ์ฅํด๋ ๋ค์ ๋ช ๋ น์ ์คํํ๋ค.
๊ทธ๋ฆฌ๊ณ undo()๊ฐ ํธ์ถ๋๋ฉด ์ ์ฅํด๋์๋ ์ํ๋ก ๋์๊ฐ๋ฉด ๋๋ค.
๋ค์ค ๋ช ๋ น ์คํ ์ทจ์, ์ฌ์คํ
๋ค์ค ๋ช ๋ น ์คํ ์ทจ์๋ ์ด๋ ต์ง ์๋ค.
์ต๊ทผ n๊ฐ์ ๋ช ๋ น์ ์ ์ฅํ๋ ๋ฐฐ์ด(๋ช ๋ น ์คํธ๋ฆผ)์ ๋๊ณ , ํ์ฌ ๋ช ๋ น์ ๊ฐ๋ฅดํค๋ ํฌ์ธํฐ๋ง ์์ผ๋ฉด ๋๋ค.

๋ง์ฝ ์ ๊ทธ๋ฆผ๊ฐ์ ์ํฉ์์ ๋ช ๋ น ์ทจ์ํ๋ฉด, Current ํฌ์ธํฐ๊ฐ ๊ฐ๋ฆฌํค๋ Command์์ undo()๋ฅผ ํธ์ถํ๊ณ Current๊ฐ ๋ค์ Command๋ฅผ ๊ฐ๋ฆฌํค๊ฒ ํ๋ฉด ๋๋ค. ์ด๋ฐ ๋ฐฉ์์ผ๋ก ์ฌ๋ฌ๋ฒ undo()๊ฐ ๊ฐ๋ฅํ๋ค.
๋ช ๋ น ์ทจ์๋ฅผ ์ทจ์ํ๊ณ ์ถ๋ค๋ฉด, ์ฆ, ์ฌ์คํํ๊ณ ์ถ๋ค๋ฉด undo()์ดํ Current ํฌ์ธํฐ๊ฐ ๊ฐ๋ฅดํค๊ณ ์๋ Command์ execute()๋ฅผ ์คํํ๋ฉด ๋๋ค.
Current์์ undo()๋ฅผ ์คํํ ๋ค, ์๋ก์ด ๋ช ๋ น์ด ์ถ๊ฐ๋๋ฉด Current๋ค์ ๋ช ๋ น๋ค์ ๋ชจ๋ ์ญ์ ํ ๋ค์ ์๋ก์ด ๋ช ๋ น์ ์ถ๊ฐํ๋ฉด ๋๋ค.
๋์ : ๊ฒ์ ํ๋ก๊ทธ๋๋ฐ ํจํด
'๐ฅ๏ธ Study Note > Design Patteren' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| ํ๋กํ ํ์ (ProtoType) ํจํด (0) | 2023.06.19 |
|---|---|
| ๊ด์ฐฐ์(Observer) ํจํด (0) | 2023.06.08 |
| ๊ฒฝ๋(FlyWeight) ํจํด (2) | 2023.06.07 |
| ๋์์ธ ํจํด์ด๋? (0) | 2023.06.05 |