• 검색 결과가 없습니다.

상태를클래스로표현한다 Chapter 19. State Java 로배우는디자인패턴입문

N/A
N/A
Protected

Academic year: 2022

Share "상태를클래스로표현한다 Chapter 19. State Java 로배우는디자인패턴입문"

Copied!
26
0
0

로드 중.... (전체 텍스트 보기)

전체 글

(1)

2012-1

덕성여자대학교 정보미디어대학

교재: 자바언어로배우는디자인패턴입문(개정판)/YukiHiroshi저/김윤정역/영진닷컴

(2)

어떤 것을 클래스로 표현할지는 설계하는 사람의 마음이다.

클래스에 대응하는 구체적인 ‘사물’이 현실에 존재하는 경우 도 있고, 존재하지 않는 경우도 있다.

State 패턴은, ‘상태’를 클래스로 표현한 것이다.

– 클래스를 교체함으로써, ‘상태의 변화’를 나타낼 수 있고,

– 새로운 상태를 추가해야 할 때 무엇을 프로그램하면 되는지 명 확해진다.

(3)

금고경비 시스템

– 시각마다 경비의 상태가 변화는 금고경비 시스템 – 호출 상황을 화면에 표시한다.

– 프로그램상의 1초를 현실 세계의 1시간으로 가정한다.

3

(4)
(5)

State 패턴을 사용하지 않는 의사 코드 (pseudo code)

5 class 금고경비시스템 {

금고 사용시에 호출되는 메소드(){

if(주간) {

경비센터에 이용기록 } else if (야간) {

경비센터에 비상사태 통보 }

}

비상벨 사용시에 호출되는 메소드(){

경비센터에 비상벨의 통보 }

일반 통화시에 호출되는 메소드(){

if(주간) {

경비센터 호출 } else if (야간) {

경비센터의 자동응답기 호출 }

} }

(6)

State 패턴을 사용한 의사 코드(pseudo code)

– 앞의 코드와 달리, 파묻혀 있던 ‘상태’를 외부로 끌어냄

 따라서, 상태를 체크하기 위한 if 문이 없다

주간이라는 상태를 표현한 클래스 { 금고 사용시에 호출되는 메소드(){

경비센터에 이용기록;

}

비상벨 사용시에 호출되는 메소드(){

경비센터에 비상벨의 통보;

}

일반 통화시에 호출되는 메소드(){

경비센터의 호출;

} }

야간이라는 상태를 표현한 클래스 { 금고 사용시에 호출되는 메소드(){

경비센터에 비상사태의 통보;

}

비상벨 사용시에 호출되는 메소드(){

경비센터에 비상벨의 통보;

}

일반 통화시에 호출되는 메소드(){

경비센터의 자동응답기 호출;

} }

(7)

7

(8)
(9)

State 인터페이스

– 금고의 상태를 나타냄

– 다음 이벤트가 발생했을 때 호출되는 인터페이스(API)를 제공

 시각이 설정될 때 => doClock( )을 호출함

 금고가 사용될 때 => doUse( )를 호출함

 비상벨이 울릴 때 => doAlarm( )을 호출함

 일반 통화를 할 때 => doPhone( )을 호출함

– 각 메소드의 형식 인자 Context

 상태를 관리하거나 실제 경비센터를 호출하는 일을 하는 클래스

9

(10)

DayState 클래스

– 주간의 상태를 나타내는 클래스

– 하나의 상태만 필요하므로, Singleton 패턴을 사용함

 DayState 타입의 객체를 static 으로 선언하고 인스턴스 한 개을 생성함

 생성자를 private으로 선언함

– doClock( ): 시각을 설정하는 메소드

 인자에서 제공된 시각이 야간의 시각이면, 시스템의 상태를 야간 으로 바꾼다.

– “주간 상태”에서 하는 일을 표현하는 메소드 (Context의 메소 드를 이용한다)

 doUse( ): 주간에 금고를 사용했음을 기록

 doAlarm( ): 비상벨로 경비센터를 호출함

 doPhone( ): 경비센터에 일반통화를 함

(11)

NightState 클래스

– 야간의 상태를 나타내는 클래스 – DayState 클래스와 비슷하다.

11

(12)

Context 인터페이스

– 상태를 관리하거나 경비센터를 실제로 호출하는 클래스를 위 한 인터페이스를 제공한다.

(13)

13

(textScreen) BorderLayout

매니저

Button 객체들 Panel 객체

NORTH

CENTER

SOUTH

(14)

SafeFrame 클래스

– GUI를 사용해서, 금고경비 시스템을 실현한다.

– Context 인터페이스를 구현함

– state 필드: 금고의 현재 상태를 저장하는 변수

 초기는 ‘주간’ 상태임

– 생성자에서 하는 일

 배경색의 설정

 레이아웃 매니저의 설정

 부품의 배치

 리스너(Listener)의 설정

– addActionListener 메소드를 이용하여 ActionListener를 구현한 객체 를 버튼에 등록한다.

– 버튼이 눌러지면 등록된 ActionListener 객체의 actionPerformed( ) 를 호출한다.

(15)

SafeFrame 클래스(계속)

– 버튼의 ActionListener는 SafeFrame 자신이다.

– actionPerformed( )

 눌러진 버튼의 종류에 따라 state.doUse(this) / state.doAlarm(this) / state.doPhone(this) 중 하나를 호출한다.

 현재 상태가 주간인지 야간이지 체크하는 코드가 필요없다.

– setClock( )

 시간 설정을 위해서 클라이언트(Main)가 호출하는 메소드

– callSecurityCenter( )

 경비센터에 대한 호출을 표현함

– recordLog( )

 경비센터의 로그에 기록하는 일을 표현함

15

(16)

Main 클래스

– SafeFrame 인스턴스를 한 개 만든 후,

– 1초 간격으로 SafeFrame의 setClock( ) 메소드를 호출한다.

 Thread.sleep(1000) 문장을 사용함.

(17)

“금고사용”버튼이 눌려진 후에 doUse( )를 실행하는 모습

17

주간에서 야간으로 바뀐다.

(18)

State(상태)의 역할

– 상태를 나타내는 역할

– 각 상태에 따라 다른 행동을 하는 통일된 인터페이스(API)를 결정함

– 예제에서는, State 인터페이스가 해당됨

ConcreteState(구체적인 상태)의 역할 – 구체적인 개개의 상태를 표현하는 역할 – State 역할이 결정한 인터페이스를 구현함

– 예제에서는, DayState와 NightState 클래스가 해당됨

(19)

Context(상황, 전후관계, 문맥)의 역할

– 현재의 상태를 나타내는 ConcreteState 역할을 가지고 있음 – State 패턴 이용자가 필요로 하는 인터페이스를 결정함

– 예제에서는 Context 인터페이스와 SafeFrame 클래스가 해당 됨.

19

(20)

분할해서 통치하라

– “divide and conquer”

 복잡하고 규모가 큰 프로그램을 다룰 때, 우선 작은 문제로 나누 어라. 그래도 풀기 어려우면 더 작은 문제로 나누어라.

– State 패턴에서는

 개개의 구체적인 상태를 각각 클래스로 나누어서 표현함으로써 문제를 분할함

– 상태의 종류가 많을수록 유용함

 State 패턴을 사용하지 않는다면, 계속해서 상태를 검사하는 조건 문이 필요하다.

 예: 상태가 10가지라면, if-else-if 문이 10개 정도 필요함

(21)

상태에 의존한 처리

– Main 클래스가 SafeFrame의 setClock( ) 메소드를 호출해서 시 각을 설정해달라고 부탁함

– setClock( ) 메소드 안에서는, state.doClock(this, hour)를 호출 하여 현재 state에 그 처리를 위임함

– 현재 state가 무엇이냐에 따라 행동이 달라진다. 즉, “상태에 따 라 행동이 달라지는 처리”이다.

21

(22)

새로운 상태를 추가하는 것은 간단

– 예제 프로그램에서는, State 인터페이스를 구현한 XXXState 클 래스를 만들어 필요한 메소드를 구현하기만 하면 된다.

(23)

STD(State Transition Diagram)

– 시스템의 상태 변화를 표현하기 위해 많이 사용되는 다이어그램

금고의 상태 변화를 State Transition Diagram으로 표현해 보면...

23

DayState NightState

hour < 9 || 17 <= hour

9 <= hour && hour < 17

(24)

Singleton 패턴

Flyweight 패턴

(25)

시스템의 각 상태를 클래스로 표현한 State 패턴

25

(26)

19-1

– Context 인터페이스를 추상 클래스로 정의하지 않은 이유는?

 다중 상속과 관련이 있음

19-2

– 주간, 야간 범위를 변경하는 경우, 코드 수정은 어떻게 해야 하는가?

19-3

– “점심시간” 이라는 상태를 추가하시오.

19-4

– “비상시”라는 상태를 추가하시오.

참조

관련 문서