방문 클래스 정의
방문방문 클래스
Door
+ doOpen() :void
+ doClose() :void
+ doLock() :void
+ doUnlock() :void
+ isWayEmpty() :boolean
7.
Door
- state :DoorState= Opend
+ doOpen() :void
+ doClose() :void
+ doLock() :void
+ doUnlock() :void
«enumeratio...
DoorState
Opend
Closed
Locked
방문 클래스 + 방문 상태
방문 상태 정의
8.
방문 상태도
방문 클래스
방문상태도
Locked
Opened Closed
Initial
doClose [doorWay->IsWayEmpty]
doLockdoUnlock
doOpen
create
Door
- state :DoorState = Opend
+ doOpen() :void
+ doClose() :void
+ doLock() :void
+ doUnlock() :void
«enumeratio...
DoorState
Opend
Closed
Locked
9.
방문 상태표(State Chart)
방문상태도
Locked
Opened Closed
Initial
doClose [doorWay->IsWayEmpty]
doLockdoUnlock
doOpen
create
State
Next State
S0
Locked
S1
Opened
S2
Closed
S3
Initial
S0Locked
doUnlock
S1Opened
doCl... do...
S2Closed
doLock doOpen
S3Initial
create
방문 상태표(state chart)
State Machine Diagram
•사건(Event)에 따른 상태간 전이(Transition) 및 전이 조건(Guard) 그리고 상태 변경에
따른 행위(Action)를 정의한 다이어그램
• 제어 플로우가 아닌 상태 변경과 관련된 프로세스에 적합
• 라이프 사이클 전체를 취급 하거나 동시 동작을 기술이 필요 할때 사용
12.
● entry :상태 진입시 실행될 액션
● exit : 상태 진출시 실행될 액션
● do : 상태안에서 반복 실행될 처리, 상태 이동시 중단
State Machine 표기법
13.
State Machine 표기법
Trigger
●상태 전이가 발생(촉발) 하는 원인으로 보통 이벤트라 칭한다.
● signal, event, change, passage time 4가지 발생(촉발) 타입
Guard
● 상태 이동 성립 조건, 성립 조건이 True일경우만 상태 전이가 가능하다.
Effect
● 상태 이동에 따른 효과, 실행 액션
Source State Target State
trigger [guard] / effect
훌륭한 DA 한분이상태를 잘 정의
O2O주문 모델링 - 주문 상태
접수구분 - 배정상태 - 수락결과 - 출고유형
1 개월 설계 및 기술 검토
23.
일반 주문 상태약 19개
O2O주문 모델링 - 주문 상태
접수구분 - 배정상태 - 수락결과 - 출고유형
내가 생각 했던 사용 기대 용어
배정접수,
배정확정,
수락요청
수락, 거절,
출고지시,
출고완료
….
24.
공식 용어가 아닌코드 값으로 대화
10-10
10-20
20-10
30-10
30-20
20-99
....
배정접수,
배정확정,
수락요청
수락, 거절,
출고지시,
출고완료
….
사용 기대 용어 실제 사용 용어
X
O2O주문 모델링 - 주문 상태
접수구분 - 배정상태 - 수락결과 - 출고유형
상태 코드의 비밀
A군담당 B군 담당(나) C군 담당
10
20 30 41 50 9030
31
40
상태전이 = 현재 상태 +1 or + 10
29.
상태도를 그리기 전까지...
-상태 전이는 다음과 같았다.
상태전이 = 현재 상태 +1 or + 10
- 다음 4가지 값의 조합으로 주문상태를 식별 한다.
접수구분 - 배정상태 - 수락결과 - 출고유형
- 각 상태 변경시 entry action, guard 등이 다양하게 존재
- 각 개인이 이해하는 수준이 틀리고 일치 하지 않음
A군 B군
C군
30.
갱신! 갱신! 갱신!상태도 최종 완성
- 교환에 대한 상태도 추가
- 반품에 대한 상태도 추가
- 취소에 대한 상태도 추가
코드가 직관적? 이고빠르게 결과를 낼수 있다… 단 변화에 취약
1안 : 닥 개발
if if if if if... huk huk huk
public void insertQuarter() {
if (state == HAS_QUARTER) {
System.out.println("You can't insert another quarter");
} else if (state == NO_QUARTER) {
state = HAS_QUARTER;
System.out.println("You inserted a quarter");
} else if (state == SOLD_OUT) {
System.out.println("You can't insert a quarter, the machine is sold out");
} else if (state == SOLD) {
System.out.println("Please wait, we're already giving you a gumball");
}
}
public void turnCrank() {
if (state == SOLD) {
System.out.println("Turning twice doesn't get you another gumball!");
} else if (state == NO_QUARTER) {
System.out.println("You turned but there's no quarter");
} else if (state == SOLD_OUT) {
System.out.println("You turned, but there are no gumballs");
} else if (state == HAS_QUARTER) {
System.out.println("You turned...");
state = SOLD;
34.
코드가 깔끔해지고 “Ifhell” 에서 벗어 날 수 있음
하지만 각 상태별로 의존성 제약이 생김
2안 : State Pattern 적용
public void insertQuarter() {
state.insertQuarter();
}
public void turnCrank() {
state.turnCrank();
state.dispense();
}
깔금 깔금
class HasQuarterState implements State {
...
}
class HasQuarterState implements State {
...
}
상태로직을 담은 상태 클래스
35.
State Pattern
Context
+ request():void
«interface»
State
+ handle() :void
껌배출
껌매진
동전없음
동전있음
상태를 기반으로 하는 행동을 캡슐화 하고 현재 상태에 위임 한다.
• 객체 내부 상태가 바뀜에 따라 객체의 행동을 바꿀 수 있다.
• OCP(Open Close Principal) 따른다.
(상태를 무한 증가 시킬수 있음…)
• 바뀌는 부분인 상태를 캡슐화
• 전략패턴과 비슷
S2M Feature
Easy touse flat one level state machine for simple use cases.
Hierarchical state machine structure to ease complex state configuration.
State machine regions to provide even more complex state configurations.
Usage of triggers, transitions, guards and actions.
Type safe configuration adapter.
Builder pattern for easy instantiation for use outside of Spring Application context
Recipes for usual use cases
Distributed state machine based on a Zookeeper
State machine event listeners.
Spring IOC integration to associate beans with a state machine.
상태머신 요소(상태,이벤트, 가드)식별
static enum States {
Opend, Closed, Locked
}
static enum Events {
Open, Close, Lock, Unlock
}
@Bean
static Guard<States, Events> isEmptyDoorWay() {
return new Guard<States, Events>() {
@Override
public boolean evaluate(StateContext<States, Events> context) {
return new Random().nextBoolean();
}
};
}
➜ Enum Type 상태 정의
➜ Enum Type 이벤트 정의
➜ Guard 즉 상태 전이 가능 여부 평가
41.
상태머신 Configuration
@Configuration
@EnableStateMachine
public staticclass Config1 extends EnumStateMachineConfigurerAdapter<States, Events> {
@Override
public void configure(StateMachineStateConfigurer<States, Events> states) throws Exception {
states
.withStates()
.initial(States.Closed)
.states(EnumSet.allOf(States.class));
}
@Override
public void configure(StateMachineTransitionConfigurer<States, Events> transitions) throws Exception {
transitions
.withExternal()
.source(States.Opend).target(States.Closed).event(Events.Close)
.guard(isEmptyDoorWay())
.and()
.withExternal()
.source(States.Closed).target(States.Opend).event(Events.Open);
}
}
➜ 상태 등록 Config
➜ 상태 동작(이벤트, 가드) config
42.
S2M에서 제공하는 상태
States
HierarchicalStates
Distributed States
Regions
Transitions
Guards
Actions
Pseudo States
Initial State
Terminate State
History State
Choice State
Fork State
Join State
43.
도입결과
1. 현격히 줄어즌코드량(IF문 제거)
2. 주문 상태 전이가 명확 해지고 좀비 상태가 줄어듬
정의하지 않은 상태전이가 일어나는 현상
3. 컴포넌트간 역할이 명확해짐
모든 상태 변경 처리는 S2M이 처리… but 일부분은 적용하지 못하고 프로젝트 종료
프로젝를 겸한 2개월 안정화 기간동안 문제가 발생한 곳이 주로 S2M을 적용하지 못한 곳
44.
마치며
1. 상태머신을 적용하기위해선 상태도를 반드시 그립니다.
2. S2M GitHub의 Example을 꼭 활용하세요
3. S2M 사용시 1.0.2 이상 사용하세요 @Scope 적용 가능
(Spring 4.2이에에서 @Scope을 사용하기 위해 약간의 수정 필요)