Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 주짓떼로
- git
- 디자인패턴
- 영화감상
- 노드
- 파이썬
- JavaScript
- 개발
- 자바스크립트
- graphQL
- 주짓수
- 엄티로드
- 리액트
- Node
- 솔로드릴
- web
- 하프가드
- development
- nodejs
- 주짓떼라
- 드릴
- 클로즈가드
- REACT
- 프로그래밍
- 영화
- 영화리뷰
- 웹개발
- 개발자
- Express
- Redux
Archives
- Today
- Total
As i wish
[Design pattern] State pattern (스테이트 패턴, 상태 패턴) 본문
오늘은 스테이트 패턴 에 대하여 포스팅 해보겠습니다.
스테이트 패턴
객체의 내부 상태과 바뀜에 따라서 객체의 행동을 바꿀 수 있다. 마치 객체의 클래스가 바뀌는 것과 같은 결과를 얻을 수 있다.
일단, 결론부터 얘기하자면 스테이트 패턴은 if, switch 문을 캡슐화, 분리해서 변경하여 사용 할 수 있게 됩니다.
먼저 책에서 얘기한 예제를 들어서 설명해 보겠습니다.
뽑기에 대하여 예를 들었는데요.
상태
동전이 있는 상태
동전이 없는 상태
알맹이 판매 상태
알맹이 매진 상태
행동
동전 투입
동전 반환
손잡이 돌림
알맹이 내보내기 (알맹이 매진 상태 또는 동전이 없는 상태 로 변경)
위 처럼 사용자에 행동에 따라서 상태를 변경 시켜줘야 하는데요. 이때 보통 대부분 If문을 사용하여 아래처럼 코드를 구성 하는데, 사실 if문의 길이가 길어지면 (switch 문도 동일) 상당히 관리하기 어려워지고 유지보수도 어려워 집니다. 그래서 '상태 패턴'을 사용하여 이를 해결 할 수 있게 해주죠.
if (상태 === 동전이 있는 상태) {
...
} else if (상태 === 동전이 없는 상태) {
...
}
이렇게 상태 (State) 들을 Context에 정의하고 상태가 바뀔 때 마다 Context 객체에서 상태를 변경해주면 됩니다. 그럼 Client 에서 객체가 바뀌는 듯한 효과를 얻을 수 있고 If 문 이나 Switch 문같이 조건문도 필요 없이 상태 객체들만 잘 정의해 주면 되죠.
따라서 복잡한 조건문 없이도 각각의 상태의 따라 다른 효과를 낼 수 있게 됩니다.
# -*- coding: utf-8 -*-
# State Pattern
import abc
class GamballMachine:
def __init__(self, numberOfGamBalls):
self.hasQuaterState = HasQuaterState(self)
self.noQuaterState = NoQuaterState(self)
self.soldState = SoldState(self)
self.soldOutState = SoldOutState(self)
self.state = self.noQuaterState
self.count = numberOfGamBalls
def insertQuater(self):
self.state.insertQuater()
def ejectQuater(self):
self.state.ejectQuater()
def turnCrank(self):
self.state.turnCrank()
self.state.dispense()
def setState(self, state):
self.state = state
def getHasQuaterState(self):
return self.hasQuaterState
def getNoQuaterState(self):
return self.noQuaterState
def getSoldState(self):
return self.soldState
def getSoldOutState(self):
return self.soldOutState
def releaseBall(self):
if self.count != 0:
self.count = self.count -1
print 'Release gamball'
def getCount(self):
return self.count
class State:
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def insertQuater(self, gamball_machine):
pass
@abc.abstractmethod
def ejectQuater(self, gamball_machine):
pass
@abc.abstractmethod
def turnCrank(self, gamball_machine):
pass
@abc.abstractmethod
def dispense(self, gamball_machine):
pass
class HasQuaterState(State):
def __init__(self, gamball_machine):
self.gamball_machine = gamball_machine
def insertQuater(self):
print 'Already has quater'
def ejectQuater(self):
print 'Eject quater'
self.gamball_machine.setState(self.gamball_machine.getNoQuaterState())
def turnCrank(self):
self.gamball_machine.setState(self.gamball_machine.getSoldState())
def dispense(self):
pass
class NoQuaterState(State):
def __init__(self, gamball_machine):
self.gamball_machine = gamball_machine
def insertQuater(self):
print 'Insert quater'
self.gamball_machine.setState(self.gamball_machine.getHasQuaterState())
def ejectQuater(self):
print 'Please input quater first'
def turnCrank(self):
print 'Please input quater first'
def dispense(self):
pass
class SoldState(State):
def __init__(self, gamball_machine):
self.gamball_machine = gamball_machine
def insertQuater(self):
pass
def ejectQuater(self):
pass
def turnCrank(self):
pass
def dispense(self):
self.gamball_machine.releaseBall()
if self.gamball_machine.getCount() > 0:
self.gamball_machine.setState(self.gamball_machine.getNoQuaterState())
else:
self.gamball_machine.setState(self.gamball_machine.getSoldOutState())
class SoldOutState(State):
def __init__(self, gamball_machine):
self.gamball_machine = gamball_machine
def insertQuater(self):
print 'Gammball was sold out, Eject quater'
def ejectQuater(self):
print 'Insert quater fist'
def turnCrank(self):
print 'Please insert quater first'
def dispense(self):
pass
# Client
gamballMachine = GamballMachine(2)
print '** Insert and Eject **'
gamballMachine.insertQuater()
gamballMachine.ejectQuater()
print '\n ** Insert and Turncrank **'
gamballMachine.insertQuater()
gamballMachine.turnCrank()
print '\n ** Notinsert and Turncrank **'
gamballMachine.turnCrank()
print '\n ** Set soldout state and turncrank **'
gamballMachine.insertQuater()
gamballMachine.turnCrank()
gamballMachine.turnCrank()
print '\n ** Insert quater when sold out **'
gamballMachine.insertQuater()
'Design Pattern' 카테고리의 다른 글
[Design pattern] Proxy pattern (프록시 패턴) (0) | 2019.06.10 |
---|---|
[Design pattern] Composite pattern (컴포지트 패턴) (0) | 2019.05.23 |
[Design pattern] Iterator pattern (이터레이터 패턴) (0) | 2019.05.13 |
[Design pattern] Template method pattern (템플릿 메서드 패턴) (0) | 2019.05.05 |
[Design pattern] 데코레이터 vs 어댑터 vs 퍼사드 패턴 (0) | 2019.04.22 |
Comments