- 전략 패턴(Strategy Pattern)이란?
객체가 수행하는 여러가지 행동(행위) 중에서 상황에 맞는 적절한 전략을 선택해서 실행하는 패턴을 말한다.
쉽게 말해 "알고리즘을(행위를) 통째로 바꿔서 적용할 수 있는 패턴" 이라고 생각하면 된다.
좀 더 쉽게 이해하기 위해서 게임으로 예시를 들어보자!
RPG 게임에서 적 캐릭터(몬스터)가 있다고 가정해보자.
몬스터는 플레이어와의 거리가 가까우면 근접으로 공격하고 멀다면 원거리에서 공격한다.
이 몬스터만이 가지고 있는 고유의 패턴을 만들때 전략 패턴을 사용하는 것!
또는 보스 몬스터만이 가지고 있는 패턴이 존재할 수 있는데 이 때에도 전략 패턴을 사용할 수 있다.
- HP 100%~50% → 원거리 공격 전략
- HP 50%~20% → 돌진 공격 전략
- HP 20% 이하 → 발악 기술 전략
이런 식으로 패턴을 설계해서 구현할 수 있는 것!
- 그렇다면 전략 패턴을 어떻게 사용하나요?
이번에도 간단한 c# 게임 코드를 통해서 예를 들어보자!
1. 우선 기술 전략 인터페이스를 먼저 정의한다!
// 스킬 전략
public interface ISkillStrategy
{
string SkillName { get; }
void Skill();
}
2. 전략 인터페이스를 상속받아 다양한 스킬 전략을 만든다!
// 근접 기술 전략
public class Skill_Melee : ISkillStrategy
{
public string SkillName => "근접 기술 A";
public void Skill()
{
Console.WriteLine($"{SkillName}로 공격!");
}
}
// 원거리 기술 전략
public class Skill_Range : ISkillStrategy
{
public string SkillName => "원거리 기술 B";
public void Skill()
{
Console.WriteLine($"멀리서 {SkillName}로 공격!");
}
}
// 치유 기술 전략
public class Skill_Heal : ISkillStrategy
{
public string SkillName => "치유 기술 C";
public void Skill()
{
Console.WriteLine($"{SkillName}로 상처를 치료!");
}
}
3. 적용할 대상에게(클래스한테) 전략을 적용시킨다.
// 몬스터에게 전략 적용
public class Enemy1 {
private string enemyName = "고블린";
private ISkillStrategy skillStrategy;
// 전략 변경
public void SetSkillStrategy(ISkillStrategy skillStrategy)
{
this.skillStrategy = skillStrategy;
}
// 스킬 사용
public void takeSkill()
{
Console.WriteLine($"\n{enemyName}이 {skillStrategy.SkillName} 기술을 사용했다!");
skillStrategy.Skill();
}
}
3-1. 사용 테스트 1
internal class Program
{
static void Main(string[] args)
{
Enemy1 enemy = new Enemy1();
// 근접 기술 사용
enemy.SetSkillStrategy(new Skill_Melee());
enemy.takeSkill();
// 전략 수정 후 원거리 기술 사용
enemy.SetSkillStrategy(new Skill_Range());
enemy.takeSkill();
// 전략 수정 후 아군 치유 기술 사용
enemy.SetSkillStrategy(new Skill_Heal());
enemy.takeSkill();
}
}
테스트 결과
이런 식으로 행동을 상황에 맞게 교체가능한 전략으로 분리해주는 패턴이다!
이제 마지막으로 상황에 맞게끔 사용한다고 예시를 들어보자면
3-2. 사용 테스트 2
internal class Program
{
static void Main(string[] args)
{
Enemy1 enemy = new Enemy1();
int enemyMaxHp = 30; // 최대 체력
int enemyCurHp = 14; // 현재 체력
int playerDistance = 5; // 플레이어과의 거리
// 상황에 따른 전략 결정
if (enemyCurHp <= enemyMaxHp * 0.5)
{
enemy.SetSkillStrategy(new Skill_Heal());
}
else if (playerDistance <= 5)
{
enemy.SetSkillStrategy(new Skill_Melee());
}
else
{
enemy.SetSkillStrategy(new Skill_Range());
}
// 전략에 맞는 기술 사용
enemy.takeSkill();
}
}
이렇게 현재 체력이 최대 체력의 절반 이하라서 전략을 치유 스킬 전략으로 바꿔서 사용한 것이다!
그 외에도 스킬에 재사용 대기시간을 부여하거나,
랜덤값을 줘서 무작위 기술을 사용하도록 설계하거나
전략을 원하는데로 교체하도록 구현할 수 있다!