디자인패턴 - 전략패턴(Strategy Pattern) (2023.09.25)

최장범·2023년 9월 25일
0

TIL

목록 보기
34/50

전략 패턴이란?

  • 특정 작업을 독립적으로 정의하고 캡슐화 하여, 해당 작업을 *동적으로 교체할 수 있도록 하는 패턴
    (* 동적 - 코드가 실행되는 중에 안의 내용이 실시간으로 바뀌어 처리할수 있는)

  • 캡슐화
    - 캡슐화란, 클래스들이 서로 다른 부분들을 찾아내서 그 클래스들의 공통점에서 분리를 하는 작업을 말합니다.


전략 패턴을 사용하는 이유

  • 우리는 코드의 재사용성을 줄이기 위해 상속(Inheritance)를 사용하는데 이를 잘못 사용하면 하위의 서브클래스에 의도하지 않던 변화를 주게 되고 이를 해결하기 위해 메서드를 계속해서 오버라이드 하게 되는 일이 일어나게 됩니다.

  • 예를 들어 Monster라는 클래스가 있습니다. 몬스터들에는 고블린, 트롤, 하피 등이 있다고 가정합니다. 이 몬스터들의 공통점은 플레이어를 공격한다는 점이 있습니다. 차이점으로는 울음소리가 다르다는 것과 하피만 유일하게 날 수 있다는 점입니다.

  • 그렇다면 우리는 이 차이점에 해당하는 행동 만을 목적으로 하는 행동 인터페이스 클래스를 구현해야합니다.

-interface IFlyBehavior()


-interface ICrawlBehavior()


실제 예시

//행동 인터페이스
public interface IFlyBehavior
{
    void Fly();
}

public interface ICrawlBehavior
{
    void Crawl();
}
// 날 수 있는 행동 구현
public class FlyWithWings : IFlyBehavior
{
    public void Fly()
    {
        Console.WriteLine("날개로 납니다.");
    }
}

// 날지 못하는 행동 구현
public class FlyNoWay : IFlyBehavior
{
    public void Fly()
    {
        Console.WriteLine("날지 못합니다.");
    }
}

// 쿠오오오 소리를 내는 행동 구현
public class Quaoo : ICrawlBehavior
{
    public void Crawl()
    {
        Console.WriteLine(" 쿠오오오 소리를 냅니다.");
    }
}

// 끄익끄익 소리를 내는 행동 구현
public class Squeak : IQuackBehavior
{
    public void Crawl()
    {
        Console.WriteLine("끄익끄익 소리를 냅니다.");
    }
}
// 하아아아아 소리를 내는 행동 구현
public class Haaaa : IQuackBehavior
{
    public void Crawl()
    {
        Console.WriteLine("하아아아아 소리를 냅니다.");
    }
}
public abstract class Monster
{
    protected IFlyBehavior flyBehavior;
    protected ICrawlBehavior crawlBehavior;

    public Monster()
    {
    }

    public abstract void Display();

    public void PerformFly()
    {
        flyBehavior.Fly();
    }

    public void PerformCrawl()
    {
        quackBehavior.Crawl();
    }

    public void AttackPlayer()
    {
        Console.WriteLine("모든 몬스터는 플레이어를 공격합니다.");
    }
}
public class Goblin : Monster
{
    public Goblin()
    {
        flyBehavior = new FlyNoway();
        quackBehavior = new Squeak();
    }

    public override void Display()
    {
        Console.WriteLine("고블린 몬스터");
    }
}

public class Troll : Monster
{
    public Troll()
    {
        flyBehavior = new FlyNoWay();
        quackBehavior = new Quaoo();
    }

    public override void Display()
    {
        Console.WriteLine("트롤 몬스터");
    }
}

public class Harpy : Monster
{
    public Harpy()
    {
        flyBehavior = new FlyWithWings();
        quackBehavior = new Haaaa();
    }

    public override void Display()
    {
        Console.WriteLine("하피 몬스터");
    }
}
class Program
{
    static void Main(string[] args)
    {
        Monster goblin = new Goblin();
        Monster troll = new Troll();
        Monster harpy = new Harpy();

        goblin.Display();
        goblin.PerformFly();
        goblin.PerformCrawl();

        troll.Display();
        troll.PerformFly();
        troll.PerformCrawl();
        
        harpy.Display();
        harpy.PerformFly();
        harpy.PerformCrawl();
    }
}
  • 실제 사용 되는 객체(Goblin, Troll, Harpy)는 상위 형식 (Monster)으로 만들어 질 수 있습니다.
  • 여기서 새로운 몬스터를 추가 한다고 하여도 이 새로운 몬스터 클래스가 상위클래스 Monster에 영향을 주지않고, 기존 코드를 오버라이드 해야 할 상황도 만들어지지 않습니다. 그저 PerformFly(), PerformCrawl()을 이용해 할당해주기만 하면 됩니다.

한 줄 생각

  • 이번에 공부한 디자인패턴-전략패턴을 꼭 이번 팀프로젝트의 한부분에 써보자

0개의 댓글