State Pattern
태그 :
- 개념
- - 상태를 클래스로 표현하는 패턴 , TCP연결 프로토콜
I. 의도
객체 자신의 내부 상태에 따라 행위를 변경하도록 한다. 객체가 클래스를 바꾸는 것처럼 보일 수 있다
정의: 상태를 클래스로 표현하는 패턴 , TCP연결 프로토콜
: 상태를 기반으로 한 행동을 캡슐화한 다음 위임을 통해서 필요한 행동을 선택 한다.
II. 활용
- 객체의 상태에 따라 런타임시에 행위가 바뀌어야 할 때
- 객체의 상태에 따라 수많은 조건 문장을 갖도록 오퍼레이션을 구현할 수 있는데, 어떤 경우는 동일한 조건 문장을 하나 이사으이 오퍼레이션에 중복 정의해야 할 수도 있다. 이때 객체의 상태를 별도의 객체로 정의함으로써 행위는 다른 객체와 상관없이 다양화 될 수 있다
III. 결과
- 상태에 따른 행위를 국지화해 서로 다른 상태에 대한 행위를 별도의 객체로 관리한다 – 클래스 수가 많아질수 있다
- 상태 전이 규칙을 명확하게 한다 – state 객체는 context 객체가 모순되 상태를 갖는 것을 막을 수 있다
- 상태 객체는 공유할 수 있다
관련 패턴: State 객체를 만들고 공유하기 위해서는 Flyweight 패턴을 이용하면 되고, 인스턴스는 하나이므로 Singleton이다
적용전 |
적용후 |
// 3-speed ceiling fan state machine // Not good: unwieldy "case" statement
class CeilingFanPullChain { private int m_current_state; public CeilingFanPullChain() { m_current_state = 0; } public void pull() { if (m_current_state == 0) { m_current_state = 1; System.out.println( " low speed" ); } else if (m_current_state == 1) { m_current_state = 2; System.out.println( " medium speed" ); } else if (m_current_state == 2) { m_current_state = 3; System.out.println( " high speed" ); } else { m_current_state = 0; System.out.println( " turning off" ); } } }
public class StateDemo { public static void main( String[] args ) { CeilingFanPullChain chain = new CeilingFanPullChain(); while (true) { System.out.print( "Press " ); get_line(); chain.pull(); } } static String get_line() { BufferedReader in = new BufferedReader( new InputStreamReader( System.in )); String line = null; try { line = in.readLine(); } catch (IOException ex) { ex.printStackTrace(); } return line; } } <실행 결과> // Press // low speed // Press // medium speed // Press // high speed // Press // turning off // Press // low speed // Press // medium speed // Press // high speed // Press // turning off
|
// The CeilingFanPullChain class is now a wrapper // that delegates to its m_current_state reference. // Each clause from the "before" case statement is // now captured in a State derived class.
class CeilingFanPullChain { private State m_current_state; public CeilingFanPullChain() { m_current_state = new Off(); } public void set_state( State s ) { m_current_state = s; } public void pull() { m_current_state.pull( this ); } }
interface State { void pull( CeilingFanPullChain wrapper ); }
class Off implements State { public void pull( CeilingFanPullChain wrapper ) { wrapper.set_state( new Low() ); System.out.println( " low speed" ); } }
class Low implements State { public void pull( CeilingFanPullChain wrapper ) { wrapper.set_state( new Medium() ); System.out.println( " medium speed" ); } }
class Medium implements State { public void pull( CeilingFanPullChain wrapper ) { wrapper.set_state( new High() ); System.out.println( " high speed" ); } }
class High implements State { public void pull( CeilingFanPullChain wrapper ) { wrapper.set_state( new Off() ); System.out.println( " turning off" ); } }
public class StateDemo { public static void main( String[] args ) { CeilingFanPullChain chain = new CeilingFanPullChain(); while (true) { System.out.print( "Press " ); get_line(); chain.pull(); } } static String get_line() { BufferedReader in = new BufferedReader( new InputStreamReader( System.in )); String line = null; try { line = in.readLine(); } catch (IOException ex) { ex.printStackTrace(); } return line; } } |