본문 바로가기
Design Pattern

디자인 패턴 - State Pattern

by SuldenLion 2022. 4. 27.
반응형

State Pattern :

스테이트 패턴은 객체가 특정 상태에 따라 행위를 달리하는 상황에서, 자신이 직접 상태를 체크하여 상태에 따라 행위를 호출하지 않고, 상태를 객체화하여 상태가 행동을 할 수 있도록 위임하는 패턴. / 객체의 특정 상태를 클래스로 선언하고, 클래스에서는 해당 상태에서 할 수 있는 행위들을 메서드로 정의함. / 이러한 각 상태 클래스들을 인터페이스로 캡슐화하여, 클라이언트에서 인터페이스를 호출하는 방식. / 객체의 내부 상태에 따라 스스로 행동을 변경할 수 있게 허가하는 패턴으로, 이렇게 하면 객체는 마치 자신의 클래스를 바꾸는 것처럼 보임

 

State 패턴으로 refactoring하는 주된 목적은 상태 전이를 위한 조건 로직(if문들)이 지나치게 복잡한 경우 이를 해소하는 것. 상태 전이 로직이란 객체의 상태와 이들 간의 전이 방법을 제어하는 것으로, 클래스 내부 여기저기 흩어져 존재하는 경향이 있음. State pattern을 구현한다는 것은 각 상태에 대응하는 별도의 클래스들을 만들고 상태 전이 로직을 그 클래스들로 옮기는 작업을 뜻함. 이 때 호스트 객체를 context라 부름. context객체는 상태와 관련된 기능을 state 객체에 delegate함. 상태전이는 context객체의 대리 객체를 한 state 객체에서 다른 state 객체로 바꾸는 일.

클래스 하나에 모여있던 상태 전이 로직을 꺼내어 각 상태를 나타내는 클래스로 분산시키면, 설계가 단순해져서 상태가 전이되는 방식을 좀 더 쉽게 알아볼 수 있음. 그러나 원래의 설계에서도 상태 전이 로직을 쉽게 이해할 수 있었다면, 굳이 State패턴으로 refactoring할 필요 x. 

 

State - 시스템의 모든 상태에 공통의 인터페이스를 제공. 이 인터페이스를 실체화 한 어떤 상태 클래스도 기존 상태 클래스를 대신해 교체해서 사용할 수 있음.

State를 상속받는 ConcreteState - Context 객체가 요청한 작업을 자신의 방식으로 실제 실행함. 대부분의 경우 다음 상태를 결정해 상태 변경을 Context 객체에 요청하는 역할도 수행.

Context - State를 이용하는 역할 수행. 현재 시스템의 상태를 나타내는 상태 변수 state와 실제 시스템의 상태를 구성하는 여러가지 변수가 있음. 각 상태 클래스에서 상태변경을 요청해 상태를 바꿀수 있도록 하는 메서드 setState가 제공됨. Context 요소를 구현한 클래스의 request 메서드는 실제 행위를 실행하는 대신 해당 상태 객체에 행위 실행을 위임. / 사용자가 관심있는 인터페이스를 정의 / 객체의 각 상태를 정의한 State의 구현체 인스턴스를 관리.

 

고려해야 할점 :

ㆍ하나의 상태를 클래스 하나로 명확히 표현하는 것과 상태변수의 값으로 표현하는 것 사이에서 저울질 해봐야함. - 클래스로 명확히 표현하는 것이 낫다면 State 패턴으로의 리펙토링을 고려 / State 패턴으로 리펙토링을 한 결과가 더 복잡하다면 굳이 State패턴 도입하지 않아도됨.

ㆍState 패턴은 if/else/switch를 효과적으로 제거함

ㆍ클래스의 수가 취급해야 하는 상태의 수 만큼 추가로 늘어난다는 점에 주의. (상황에 따라 장점도 됨)

ㆍ각 상태가 자신의 다음 상태를 알아야 한다는 특징이 있음. - 각 상태가 다음 상태를 모르는 것이 바람직한지 아닌지를 고려

ㆍ각각의 상태별로 똑같이 행동하는 메서드가 많다면, State 패턴이 필요하지 않을 수 있음.

ㆍ각 상태를 싱글톤으로 관리하는 것도 고려할 수 있음.

 

State패턴은 Strategy 패턴과 유사

스트레티지 패턴과 스테이트 패턴의 차이 :

스트레티지 패턴 - 사용자가 쉽게 알고리즘 전략을 바꿀수 있도록 유연성을 제공, 상속의 한계를 해결하기 위해 나온 패턴 / 클라이언트가 구체적인 알고리즘의 수행까지는 몰라도 어느정도 뭐가있는지 알아야함. 

스테이트 패턴 - 한 객체가 동일한 동작을 상태에 따라 다르게 수행해야 할 경우 사용하는 패턴 / 각 상태 구현 클래스들이 자신들의 행위를 수행하면서 직접 context객체의 상태를 변경해주기 때문에 클라이언트 입장에서는 직접 상태 조작하거나 하지않아도 됨.(클라이언트는 상태를 몰라도됨)

Strategy 패턴은 상속을 대체하려는 목적, State 패턴은 코드 내의 조건문들을 대체하려는 목적으로 사용.

 

+TCP connection에 State패턴이 사용되었다함

반응형

댓글