디자인패턴 - Strategy(전략) 패턴
Intro
Strategy 패턴(전략 패턴)이란 객체지향 설계에서 자주 사용되는 디자인 패턴 중 하나로,
특정 행위를 캡슐화하여 필요에 따라 동적으로 변경할 수 있도록 설계하는 방법입니다.
게임을 만들다보면 동일한 계열의 알고리즘을 여러군데 사용할때가 있습니다.
예를들어, ‘총’ 무기를 만든다고하면 총 종류에는 권총, 소총, 저격총 등 여러가지로 나뉘게 될것입니다.
하지만 권총, 소총, 저격총은 모두 총알을 사용하고 공격방식이 동일한 ‘총’ 베이스의 무기입니다.
만약 각 총마다의 코드를 따로 작성하게된다면 굉장히 비효율적이고, 유지보수 및 새로운 총의 추가가
적지않은 작업이 될것입니다.
전략패턴은 이러한 문제를 해결하여 코드의 의존성을 낮추고, 확장성은 높일수있는 디자인 패턴입니다.
전략 패턴 구조
전략패턴은 다음과 같은 구조로 이루어져 있습니다.
- Context
- 전략 객체를 사용하는 클래스
- 전략 객체의 메서드를 호출하여 원하는 동작 수행
- Strategy(인터페이스)
- 알고리즘을 추상적으로 정의한 인터페이스 또는 추상 클래스
- ConcreteStrategy
- Strategy를 구현한 구체적인 알고리즘 클래스
정리하자면 다음과 같습니다.
- Strategy(전략)
- “총” 계열의 무기에서 공통적으로 필요한 알고리즘을 서술한 추상클래스 또는 인터페이스입니다.
- 예를들어 총을 발사하는 “Shoot” 이라는 함수가 있습니다.
- ConcreteStrategy(구체적인 전략)
- “총” 클래스를 상속받아 권총, 소총, 저격총 등의 개별 총 스크립트를 만듭니다.
- 각 총의 특징을 반영하여 “Shoot” 함수를 구현합니다.
- Context(문맥)
- WeaponController는 가진 무기에따라 권총, 소총, 저격총 등의 전략을 선택하고 실행하는 클래스입니다.
전략패턴의 예시
위의 내용을 토대로 전략패턴을 구현해보았습니다.
먼저 베이스가될 총 클래스입니다.
// <Gun.cs> - Strategy
/// <summary>
/// "총" 계열의 베이스 클래스
/// </summary>
public abstract class Gun
{
// 발사!
public abstract void Shoot();
}
그리고, 총을 상속받는 권총, 소총, 저격총 클래스를 만들어줍니다.
// <Pistol.cs> - ConcreteStrategy
public class Pistol : Gun
{
public override void Shoot()
{
Debug.Log("권총 발사!");
}
}
// <Rifle.cs> - ConcreteStrategy
public class Rifle : Gun
{
public override void Shoot()
{
Debug.Log("소총 발사!");
}
}
// <Sniper.cs> - ConcreteStrategy
public class Sniper : Gun
{
public override void Shoot()
{
Debug.Log("저격총 발사!");
}
}
WeaponController 는 가진 무기에따라 ConcreteStrategy를 설정하고, 전략을 실행합니다.
// <WeaponController.cs> - Context
public class WeaponController : MonoBehaviour
{
private Gun myGun; // 현재 플레이어의 총
public void SetGun(Gun gun)
{
myGun = gun;
}
public void Shoot()
{
if(myGun != null)
{
myGun.Shoot();
}
else
{
Debug.Log("무기가 없습니다.");
}
}
}
플레이어는 게임이 시작되면 권총을 장착하고, 2초후에 소총을 장착하도록 했습니다.
// <Player.cs>
public class Player : MonoBehaviour
{
public WeaponController weapon;
private void Start()
{
// 권총 생성 및 장착
Gun pistol = new Pistol();
weapon.SetGun(pistol);
weapon.Shoot(); // 출력: "권총: 단발로 발사!"
// 2초 후에 소총으로 교체
Invoke(nameof(ChangeToRifle), 2f);
}
private void ChangeToRifle()
{
Gun rifle = new Rifle();
weapon.SetGun(rifle);
weapon.Shoot(); // 출력: "소총: 연발로 발사!"
}
}
댓글남기기