본문 바로가기
Programming/DesignPattern

[디자인 패턴] 스테이트(State) 패턴

by Blemish 2021. 5. 17.

Goal

  • 스테이트(State) 패턴을 이해한다.

 

스테이트(State) 패턴

 

 어떤 행위를 수행할 때 상태에 행위를 수행하도록 위임하는 패턴

 

 

 

스테이트 패턴을 설명하기 위해서 형광등 상태 다이어그램을 구현해보자.

 

Light 상태머신 다이어그램

형광등에도 다양한 기능(취침등...)이 있을 수 있지만 현 상태 머신 다이어그램에는 On, Off 구현하였다.

다이어그램에서 둥근 사각형은 상태(State)를 의미하고 화살표는 상태 전이(State Transitiion)를 의미하며 검은색 원 화살표는 시작 상태를 의미한다.

 

※상태(State)

   - 상태란 객체가 시스템에 존재하는동안, 즉 객체의 라이프 타임 동안 객체가 가질 수 있는 어떤 조건이나 상황을 표현한다.

     [액티비티(Activity)나 이벤트(Event)]

 

크게 2가지의 상태를 생각할 수 있다.

  • On상태일 떄 Off버튼을 누르면 형광등이 Off 상태가 되어 꺼진다.
  • Off상태일 때 On버튼을 누르면 형광등이 On 상태가 되어 켜진다.

Light 클래스 다이어그램

위의 Light 상태머신 다이어그램을 확인하고 클래스 다이어그램을 만들면 On, Off 변수와 형광등의 현재 상태를 나타내는 State 변수 그리고 On, Off 버튼을 눌렀을 때 호출되는 함수가 있다. 현재 형광등이 켜져 있는지 꺼져있는지만 잘 확인하면 클래스 다이어그램이 크게 문제가 없다고 판단된다.

 

  • Question
    • 만약 취침등 기능이 추가된다면?(취침등은 On상태일 때 On버튼을 한번 더 누르면 켜지게되고 취침등이 켜져 있을 때 Off키를 누르면 불이 꺼진다.) -> OnBtnPushed, OffBtnPushed 함수에 취침등에 대한 코드를 추가해야 하기 때문에 OCP에 위배된다. 

기존 코드를 수정하지 않으면서 코드를 확장성있게 변경할 수 있도록 설계해보자.

클래스 다이어그램

 

스테이트 패턴에서는 시스템의 각 상태를 클래스로 분리해 표현하고, 각 클래스에서 수행하는 행위들을 메서드로 구현한다. 그리고 이러한 상태들을 외부로부터 캡슐화하기 위해서 인터페이스를 만들어 시스템의 각 상태를 나타내는 클래스로 하여금 실체화하게 한다.

더보기

 전략패턴은 각 행위를 클래스로 분리해 표현하지만 스테이트 패턴은 시스템의 각 상태를 클래스로 분리해 표현한다.

 

기존에 Light 클래스에서 모든 행위(On, Off)들을 처리하는 방식에서 On버튼을 눌렀을 때, Off버튼을 눌렀을 때에 대한 행위를 인터페이스로 설계하고 형광등의 상태(LightOn, LightOff, LightSleeping)들을 각 클래스로 구현하였다. 

Light 클래스에서는 사용자가 On 또는 Off를 호출하게되면 현 상태에 맞게 LightOn, LightOff, LightSleeping의 OnBtnPushed, OffBtnPushed 함수를 호출하도록 변경하였다. 또한 상태가 변경되면 SetState를 통해서 현 상태(State)를 저장한다.

 

 

※싱글턴 기법을 사용한 이유는 각 상태 클래스가 다른 상태 클래스를 참조하기 위해서 사용하였다.

 

 

 

 

댓글