Skip to content

스테이트 패턴 (State pattern)

VG edited this page Dec 20, 2020 · 6 revisions

스테이트 패턴 (State pattern)

상태 패턴(state pattern)은 객체 지향 방식으로 상태 기계를 구현하는 행위 소프트웨어 디자인 패턴이다.출처: 위키백과


다이어그램

출처: 위키백과

예제

C#

상태(추상) 인터페이스

public interface State 
{
    public void Shot();
    public void InsertBullet(int count);
}

상태 클래스

//총알이 비어있는 상태
public class BulletEmptyState : State
{
    Gun gun;
    public BulletEmptyState(Gun gun)
    {
        this.gun = gun;
    }
    public void InsertBullet(int count)
    {
        Console.WriteLine("총알 " + count + "발을 넣었다.");
        gun.Bullets += count;
        if (gun.Bullets > 0)
            gun.SetState(gun.canShotState);// 총의 상태를 바꾼다. (총알이 비어있는 상태) → (총을 쏠 수 있는 상태)로 태세(상태) 변환
    }

    public void Shot()
    {
        Console.WriteLine("앗! 총알이 비어서 쏠 수 없다!\n");
    }
}

//총을 쏠 수 있는 상태
public class CanShotState : State
{
    Gun gun;
    public CanShotState(Gun gun)
    {
        this.gun = gun;
    }
    public void InsertBullet(int count)
    {
        gun.Bullets += count;
        Console.WriteLine("총알 " + count + "발을 넣었다.");
    }

    public void Shot()
    {
        Console.WriteLine("빵!");
        gun.Bullets--;
        if (gun.Bullets == 0)
            gun.SetState(gun.bulletEmptyState);// 총의 상태를 바꾼다. (총을 쏠 수 있는 상태) → (총알이 비어있는 상태)로 태세(상태) 변환
    }
}

상태 주인 클래스

public class Gun
{
    public State canShotState { get; private set; }
    public State bulletEmptyState { get; private set; }

    private State currentState;

    private int bullets;
    public int Bullets
    {
        get
        {
            return bullets;
        }
        set
        {
            bullets = value;
            Console.WriteLine("남은 총알: "+bullets+"발\n");
        }
    }

    public Gun()
    {
        canShotState = new CanShotState(this);
        bulletEmptyState = new BulletEmptyState(this);

        currentState = bulletEmptyState;
    }

    public void SetState(State state)
    {
        currentState = state;
    }

    public void InsertBullet(int count)
    {
        currentState.InsertBullet(count);
    }

    public void Shot()
    {
        currentState.Shot();
    }
}

메인 클래스

class MainClass
{
    static void Main(string[] args)
    {
        Gun gun = new Gun();
        gun.Shot();

        gun.InsertBullet(3);

        gun.Shot();
        gun.Shot();
        gun.Shot();

        gun.Shot();
    }
}

출력결과

앗! 총알이 비어서 쏠 수 없다!

총알 3발을 넣었다.
남은 총알: 3발

빵!
남은 총알: 2발

빵!
남은 총알: 1발

빵!
남은 총알: 0발

앗! 총알이 비어서 쏠 수 없다!

스트래티지 패턴(Strategy pattern)과의 유사성

전략 패턴과 상태 패턴의 구조는 매우 비슷하다.

상태 패턴의 다이어그램

전략 패턴의 다이어그램

전략 패턴과 상태 패턴의 공통점, 차이점

공통점

  • 하나의 주체자가 여러 상태전략에 의존하고 있다.

차이점

  • 전략 패턴에서는 전략에서 전략으로 자신의 전략변경하지 않는다.
  • 상태 패턴에서는 상태에서 상태로 자신의 상태변경한다.

이렇게, 둘은 같은 구조를 가지고 있지만, 다른 용도나 목적을 가지고있다.

Clone this wiki locally