{ ๋ช ๋ น ํจํด์ด๋? }
๋ช ๋ น ํจํด์ 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 |