SlideShare a Scribd company logo
1 of 23
Download to read offline
HEAD FIRST
DESIGN PATTERNS
10. 스테이트 패턴
이데아게임즈 손진화
뽑기 기계 만들기
상태
상태 전환알맹이
매진
동전
있음
동전
없음
알맹이
판매
알맹이 = 0
알맹이 > 0
동전 투입동전 반환
손잡이 돌림
알맹이 내보냄
뽑기 기계 코드 작성
상태
행동
뽑기 기계 코드 작성
변경 요청
알맹이
매진 동전
있음
동전
없음
알맹이
판매
당첨
알맹이 내보냄
알맹이 > 0
알맹이 = 0
동전 반환
손잡이 돌림
(당첨 안됨)
손잡이 돌림
(당첨)
동전 투입
알맹이 = 0
알맹이 > 0
알맹이 두 개
내보냄
코드를 변경하기 쉬운가?
새로운 상태 추가
행동 메소드에 추가되는 상태에 대한 코드 추가
* 4
QUIZ
- 이 코드에서는 OCP를 지키지 않고 있습니다
- 이런 디자인은 객체지향 디자인이라고 하기 힘듭니다
- 상태 전환이 복잡한 조건문 속에 숨어 있기 때문에 분명하게
드러나지 않습니다
- 바뀌는 부분을 전혀 캡슐화 하지 않았습니다
- 다른 기능을 더 추가하는 과정에서 기존 코드에 없던 새로운
버그가 생길 수 있습니다
QUIZ
- 이 코드에서는 OCP를 지키지 않고 있습니다
-> O
- 이런 디자인은 객체지향 디자인이라고 하기 힘듭니다
-> O
- 상태 전환이 복잡한 조건문 속에 숨어 있기 때문에 분명하게
드러나지 않습니다
-> O
- 바뀌는 부분을 전혀 캡슐화 하지 않았습니다
-> O
- 다른 기능을 더 추가하는 과정에서 기존 코드에 없던 새로운
버그가 생길 수 있습니다
-> O
새로운 디자인
- 뽑기 기계의 모든 행동에 대한 메소드가 들어있는 State
인터페이스를 정의한다
- 모든 상태를 State를 상속받은 클래스로 구현하여 한 상태에
대한 모든 행동을 해당 클래스가 책임 질 수 있도록 한다
- 기존의 조건문 코드를 제거하고 상태 클래스에 모든 작업을
위임한다
새로운 디자인
구현
구현
개선 결과
- 각 상태의 행동을 별개의 클래스로 국지화 시켰다
- 관리하기 힘든 if 선언문을 없앴다
- 각 상태를 변경에 대해서는 닫혀 있도록 하면서
GumballMachine 자체는 새로운 상태를 추가하는 확장에
대해서 열려 있도록 고쳤다 (OCP)
- 맨 처음 다이어그램에 훨씬 가까우면서 더 이해하기 좋은 코드
베이스와 클래스 구조를 만들었다
스테이트 패턴 STATE PATTERN
객체 내부의 상태가 바뀜에 따라서 객체의 행동을 바꿀 수 있다.
마치 객체의 클래스가 바뀌는 것과 같은 결과를 얻을 수 있다
스트레티지 패턴? 스테이트 패턴?
- 스트레티지 패턴은 클라이언트가 어떤 행동 클래스를 사용할
것인지 지정해준다
- 스테이트 패턴은 클라이언트가 행동 클래스를 몰라도 상관없다
알아서 행동 클래스가 변경된다
- 스트레티지 패턴은 구성을 통해 행동을 정의하는 객체를
유연하게 바꿀 수 있다
- 스테이트 패턴은 수많은 조건문을 대체하는 패턴이다
바보 같은 질문은 없습니다
- 상태 변경은 항상 상태 클래스 내에서만 이루어져야 하는지
상태 전환이 고정되어 있다면 Context에서 바꿔도 괜찮다
상태 전환이 동적으로 결정된다면 상태 클래스 내에서 처리하는
것이 좋다
- 클라이언트에서 상태 객체를 직접 사용하는 경우도 있는지
Context 외부에서 상태를 변경할 일은 없다
- 상태 객체를 여러 클래스에서 공유할 수 있는지
상태 객체 내에 자체 상태를 보관하지 않는다면 상관 없다
바보 같은 질문은 없습니다
- 스테이트 패턴을 사용하면 디자인에 필요한 클래스의 개수가
늘어나는지
클래스는 늘어나지만 유연성을 향상시키기 위한 비용으로 생각하자
실제로 클라이언트에게 노출되는 클래스의 개수가 중요하다
- 인터페이스를 추상 클래스로 만들어도 되는지
공통된 기능이 있다면 써도 좋다
당첨 기능 추가
당첨 기능 추가
코드 변경을 해야하는
부분이 줄었다
QUIZ
- 바꿔 쓸 수 있는 행동을 캡슐화 한 다음, 실제 행동은 다른
객체에게 위임한다
- 알고리즘의 각 단계를 구현하는 방법을 서브 클래스에서
구현한다
- 상태를 기반으로 하는 행동을 캡슐화 하고 행동을 현재
상태한테 위임한다
스테이트 스트레티지 템플릿 메소드
QUIZ
- 바꿔 쓸 수 있는 행동을 캡슐화 한 다음, 실제 행동은 다른
객체에게 위임한다
-> 스트레티지 패턴
- 알고리즘의 각 단계를 구현하는 방법을 서브 클래스에서
구현한다
-> 템플릿 메소드 패턴
- 상태를 기반으로 하는 행동을 캡슐화 하고 행동을 현재
상태한테 위임한다
-> 스테이트 패턴
핵심 정리
- 스테이트 패턴을 이용하면 내부 상태를 바탕으로 여러 가지
서로 다른 행동을 사용할 수 있다
- 스테이트 패턴을 사용하면 프로시저 형 상태 기계를 쓸 때와는
달리 각 상태를 클래스를 이용하여 표현하게 된다
- Context 객체에서는 현재 상태에게 행동을 위임한다
- 각 상태를 클래스로 캡슐화 함으로써 나중에 변경시켜야 하는
내용을 국지화 시킬 수 있다
- 스테이트 패턴과 스트래티지 패턴의 클래스 다이어그램은
똑같지만 그 용도는 서로 다르다
핵심 정리
- 스트레티지 패턴에서는 일반적으로 행동 또는 알고리즘을
Context 클래스를 만들 때 설정한다
- 스테이트 패턴을 이용하면 Context의 내부 상태가 바뀜에 따라
알아서 행동을 바꿀 수 있도록 할 수 있다
- 상태 전환은 State 클래스에 의해서 제어할 수도 있고 Context
클래스에 의해서 제어 할 수도 있다
- 스테이트 패턴을 이용하면 보통 디자인에 필요한 클래스의
개수가 늘어난다
- State 클래스를 여러 Context 객체의 인스턴스에서 공유하도록
디자인 할 수 있다

More Related Content

Similar to 헤드퍼스트 디자인패턴 - 스테이트

테크데이 발표자료.pptx.pdf
테크데이 발표자료.pptx.pdf테크데이 발표자료.pptx.pdf
테크데이 발표자료.pptx.pdf
Jihoon Kim
 
Devon 2011-b-5 효과적인 레거시 코드 다루기
Devon 2011-b-5 효과적인 레거시 코드 다루기Devon 2011-b-5 효과적인 레거시 코드 다루기
Devon 2011-b-5 효과적인 레거시 코드 다루기
Daum DNA
 
디자인 패턴 데코레이터 패턴
디자인 패턴 데코레이터 패턴디자인 패턴 데코레이터 패턴
디자인 패턴 데코레이터 패턴
SeongHyun Ahn
 
[0820 석재호]headfirst디자인패턴
[0820 석재호]headfirst디자인패턴[0820 석재호]headfirst디자인패턴
[0820 석재호]headfirst디자인패턴
Jaeho Seok
 

Similar to 헤드퍼스트 디자인패턴 - 스테이트 (12)

Head first디자인패턴 1~13_희민_호준
Head first디자인패턴 1~13_희민_호준Head first디자인패턴 1~13_희민_호준
Head first디자인패턴 1~13_희민_호준
 
dbt 101
dbt 101dbt 101
dbt 101
 
Stonze study week1
Stonze study week1Stonze study week1
Stonze study week1
 
테크데이 발표자료.pptx.pdf
테크데이 발표자료.pptx.pdf테크데이 발표자료.pptx.pdf
테크데이 발표자료.pptx.pdf
 
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
 
Javascript refactoring workshop
Javascript refactoring workshopJavascript refactoring workshop
Javascript refactoring workshop
 
Devon 2011-b-5 효과적인 레거시 코드 다루기
Devon 2011-b-5 효과적인 레거시 코드 다루기Devon 2011-b-5 효과적인 레거시 코드 다루기
Devon 2011-b-5 효과적인 레거시 코드 다루기
 
디자인 패턴 데코레이터 패턴
디자인 패턴 데코레이터 패턴디자인 패턴 데코레이터 패턴
디자인 패턴 데코레이터 패턴
 
[0820 석재호]headfirst디자인패턴
[0820 석재호]headfirst디자인패턴[0820 석재호]headfirst디자인패턴
[0820 석재호]headfirst디자인패턴
 
Effective java
Effective javaEffective java
Effective java
 
SLiPP 서비스를 Java에서 Scala로 전환하면서 경험담
SLiPP 서비스를 Java에서 Scala로 전환하면서 경험담SLiPP 서비스를 Java에서 Scala로 전환하면서 경험담
SLiPP 서비스를 Java에서 Scala로 전환하면서 경험담
 
Oop design principle SOLID
Oop design principle SOLIDOop design principle SOLID
Oop design principle SOLID
 

More from 진화 손

C++20 Remove std::weak_equality and std::strong_equality.pdf
C++20 Remove std::weak_equality and std::strong_equality.pdfC++20 Remove std::weak_equality and std::strong_equality.pdf
C++20 Remove std::weak_equality and std::strong_equality.pdf
진화 손
 
C++20 std::execution::unseq.pdf
C++20 std::execution::unseq.pdfC++20 std::execution::unseq.pdf
C++20 std::execution::unseq.pdf
진화 손
 
C++ 20 Unevaluated asm-declaration in constexpr functions
C++ 20 Unevaluated asm-declaration in constexpr functionsC++ 20 Unevaluated asm-declaration in constexpr functions
C++ 20 Unevaluated asm-declaration in constexpr functions
진화 손
 
C++20 Utility functions to implement uses-allocator construction.pdf
C++20 Utility functions to implement uses-allocator construction.pdfC++20 Utility functions to implement uses-allocator construction.pdf
C++20 Utility functions to implement uses-allocator construction.pdf
진화 손
 
C++ 20 std__reference_wrapper for incomplete types
C++ 20 std__reference_wrapper for incomplete typesC++ 20 std__reference_wrapper for incomplete types
C++ 20 std__reference_wrapper for incomplete types
진화 손
 
C++ 20 Stronger Unicode requirements
C++ 20 Stronger Unicode requirementsC++ 20 Stronger Unicode requirements
C++ 20 Stronger Unicode requirements
진화 손
 
C++20 Concepts library
C++20 Concepts libraryC++20 Concepts library
C++20 Concepts library
진화 손
 
C++ 20 Relaxing the range-for loop customization point finding rules
C++ 20 Relaxing the range-for loop customization point finding rulesC++ 20 Relaxing the range-for loop customization point finding rules
C++ 20 Relaxing the range-for loop customization point finding rules
진화 손
 
C++ 20 Relaxing the structured bindings customization point finding rules
C++ 20 Relaxing the structured bindings customization point finding rulesC++ 20 Relaxing the structured bindings customization point finding rules
C++ 20 Relaxing the structured bindings customization point finding rules
진화 손
 
C++20 explicit(bool)
C++20 explicit(bool)C++20 explicit(bool)
C++20 explicit(bool)
진화 손
 
C++20 Comparing unordered containers
C++20 Comparing unordered containersC++20 Comparing unordered containers
C++20 Comparing unordered containers
진화 손
 
C++20 Attributes [[likely]] and [[unlikely]]
C++20 Attributes [[likely]] and [[unlikely]]C++20 Attributes [[likely]] and [[unlikely]]
C++20 Attributes [[likely]] and [[unlikely]]
진화 손
 
C++ 20 Lambdas in unevaluated contexts
C++ 20 Lambdas in unevaluated contextsC++ 20 Lambdas in unevaluated contexts
C++ 20 Lambdas in unevaluated contexts
진화 손
 
C++20 Library support for operator<=> <compare>
C++20 Library support for operator<=> <compare>C++20 Library support for operator<=> <compare>
C++20 Library support for operator<=> <compare>
진화 손
 
C++20 Atomic std::shared_ptr and std::weak_ptr
C++20 Atomic std::shared_ptr and std::weak_ptrC++20 Atomic std::shared_ptr and std::weak_ptr
C++20 Atomic std::shared_ptr and std::weak_ptr
진화 손
 
C++20 Default member initializers for bit-fields
C++20 Default member initializers for bit-fieldsC++20 Default member initializers for bit-fields
C++20 Default member initializers for bit-fields
진화 손
 

More from 진화 손 (20)

C++20 Remove std::weak_equality and std::strong_equality.pdf
C++20 Remove std::weak_equality and std::strong_equality.pdfC++20 Remove std::weak_equality and std::strong_equality.pdf
C++20 Remove std::weak_equality and std::strong_equality.pdf
 
C++20 std::execution::unseq.pdf
C++20 std::execution::unseq.pdfC++20 std::execution::unseq.pdf
C++20 std::execution::unseq.pdf
 
C++ 20 class template argument deduction for alias templates
C++ 20 class template argument deduction for alias templatesC++ 20 class template argument deduction for alias templates
C++ 20 class template argument deduction for alias templates
 
C++ 20 Make stateful allocator propagation more consistent for operator+(basi...
C++ 20 Make stateful allocator propagation more consistent for operator+(basi...C++ 20 Make stateful allocator propagation more consistent for operator+(basi...
C++ 20 Make stateful allocator propagation more consistent for operator+(basi...
 
C++ 20 Unevaluated asm-declaration in constexpr functions
C++ 20 Unevaluated asm-declaration in constexpr functionsC++ 20 Unevaluated asm-declaration in constexpr functions
C++ 20 Unevaluated asm-declaration in constexpr functions
 
C++20 Utility functions to implement uses-allocator construction.pdf
C++20 Utility functions to implement uses-allocator construction.pdfC++20 Utility functions to implement uses-allocator construction.pdf
C++20 Utility functions to implement uses-allocator construction.pdf
 
C++ 20 std__reference_wrapper for incomplete types
C++ 20 std__reference_wrapper for incomplete typesC++ 20 std__reference_wrapper for incomplete types
C++ 20 std__reference_wrapper for incomplete types
 
C++ 20 Stronger Unicode requirements
C++ 20 Stronger Unicode requirementsC++ 20 Stronger Unicode requirements
C++ 20 Stronger Unicode requirements
 
C++20 Concepts library
C++20 Concepts libraryC++20 Concepts library
C++20 Concepts library
 
C++20 Coroutine
C++20 CoroutineC++20 Coroutine
C++20 Coroutine
 
C++ 20 Relaxing the range-for loop customization point finding rules
C++ 20 Relaxing the range-for loop customization point finding rulesC++ 20 Relaxing the range-for loop customization point finding rules
C++ 20 Relaxing the range-for loop customization point finding rules
 
C++ 20 Relaxing the structured bindings customization point finding rules
C++ 20 Relaxing the structured bindings customization point finding rulesC++ 20 Relaxing the structured bindings customization point finding rules
C++ 20 Relaxing the structured bindings customization point finding rules
 
C++20 explicit(bool)
C++20 explicit(bool)C++20 explicit(bool)
C++20 explicit(bool)
 
C++20 std::map::contains
C++20 std::map::containsC++20 std::map::contains
C++20 std::map::contains
 
C++20 Comparing unordered containers
C++20 Comparing unordered containersC++20 Comparing unordered containers
C++20 Comparing unordered containers
 
C++20 Attributes [[likely]] and [[unlikely]]
C++20 Attributes [[likely]] and [[unlikely]]C++20 Attributes [[likely]] and [[unlikely]]
C++20 Attributes [[likely]] and [[unlikely]]
 
C++ 20 Lambdas in unevaluated contexts
C++ 20 Lambdas in unevaluated contextsC++ 20 Lambdas in unevaluated contexts
C++ 20 Lambdas in unevaluated contexts
 
C++20 Library support for operator<=> <compare>
C++20 Library support for operator<=> <compare>C++20 Library support for operator<=> <compare>
C++20 Library support for operator<=> <compare>
 
C++20 Atomic std::shared_ptr and std::weak_ptr
C++20 Atomic std::shared_ptr and std::weak_ptrC++20 Atomic std::shared_ptr and std::weak_ptr
C++20 Atomic std::shared_ptr and std::weak_ptr
 
C++20 Default member initializers for bit-fields
C++20 Default member initializers for bit-fieldsC++20 Default member initializers for bit-fields
C++20 Default member initializers for bit-fields
 

헤드퍼스트 디자인패턴 - 스테이트

  • 1. HEAD FIRST DESIGN PATTERNS 10. 스테이트 패턴 이데아게임즈 손진화
  • 2. 뽑기 기계 만들기 상태 상태 전환알맹이 매진 동전 있음 동전 없음 알맹이 판매 알맹이 = 0 알맹이 > 0 동전 투입동전 반환 손잡이 돌림 알맹이 내보냄
  • 3. 뽑기 기계 코드 작성 상태 행동
  • 5. 변경 요청 알맹이 매진 동전 있음 동전 없음 알맹이 판매 당첨 알맹이 내보냄 알맹이 > 0 알맹이 = 0 동전 반환 손잡이 돌림 (당첨 안됨) 손잡이 돌림 (당첨) 동전 투입 알맹이 = 0 알맹이 > 0 알맹이 두 개 내보냄
  • 6. 코드를 변경하기 쉬운가? 새로운 상태 추가 행동 메소드에 추가되는 상태에 대한 코드 추가 * 4
  • 7. QUIZ - 이 코드에서는 OCP를 지키지 않고 있습니다 - 이런 디자인은 객체지향 디자인이라고 하기 힘듭니다 - 상태 전환이 복잡한 조건문 속에 숨어 있기 때문에 분명하게 드러나지 않습니다 - 바뀌는 부분을 전혀 캡슐화 하지 않았습니다 - 다른 기능을 더 추가하는 과정에서 기존 코드에 없던 새로운 버그가 생길 수 있습니다
  • 8. QUIZ - 이 코드에서는 OCP를 지키지 않고 있습니다 -> O - 이런 디자인은 객체지향 디자인이라고 하기 힘듭니다 -> O - 상태 전환이 복잡한 조건문 속에 숨어 있기 때문에 분명하게 드러나지 않습니다 -> O - 바뀌는 부분을 전혀 캡슐화 하지 않았습니다 -> O - 다른 기능을 더 추가하는 과정에서 기존 코드에 없던 새로운 버그가 생길 수 있습니다 -> O
  • 9. 새로운 디자인 - 뽑기 기계의 모든 행동에 대한 메소드가 들어있는 State 인터페이스를 정의한다 - 모든 상태를 State를 상속받은 클래스로 구현하여 한 상태에 대한 모든 행동을 해당 클래스가 책임 질 수 있도록 한다 - 기존의 조건문 코드를 제거하고 상태 클래스에 모든 작업을 위임한다
  • 13. 개선 결과 - 각 상태의 행동을 별개의 클래스로 국지화 시켰다 - 관리하기 힘든 if 선언문을 없앴다 - 각 상태를 변경에 대해서는 닫혀 있도록 하면서 GumballMachine 자체는 새로운 상태를 추가하는 확장에 대해서 열려 있도록 고쳤다 (OCP) - 맨 처음 다이어그램에 훨씬 가까우면서 더 이해하기 좋은 코드 베이스와 클래스 구조를 만들었다
  • 14. 스테이트 패턴 STATE PATTERN 객체 내부의 상태가 바뀜에 따라서 객체의 행동을 바꿀 수 있다. 마치 객체의 클래스가 바뀌는 것과 같은 결과를 얻을 수 있다
  • 15. 스트레티지 패턴? 스테이트 패턴? - 스트레티지 패턴은 클라이언트가 어떤 행동 클래스를 사용할 것인지 지정해준다 - 스테이트 패턴은 클라이언트가 행동 클래스를 몰라도 상관없다 알아서 행동 클래스가 변경된다 - 스트레티지 패턴은 구성을 통해 행동을 정의하는 객체를 유연하게 바꿀 수 있다 - 스테이트 패턴은 수많은 조건문을 대체하는 패턴이다
  • 16. 바보 같은 질문은 없습니다 - 상태 변경은 항상 상태 클래스 내에서만 이루어져야 하는지 상태 전환이 고정되어 있다면 Context에서 바꿔도 괜찮다 상태 전환이 동적으로 결정된다면 상태 클래스 내에서 처리하는 것이 좋다 - 클라이언트에서 상태 객체를 직접 사용하는 경우도 있는지 Context 외부에서 상태를 변경할 일은 없다 - 상태 객체를 여러 클래스에서 공유할 수 있는지 상태 객체 내에 자체 상태를 보관하지 않는다면 상관 없다
  • 17. 바보 같은 질문은 없습니다 - 스테이트 패턴을 사용하면 디자인에 필요한 클래스의 개수가 늘어나는지 클래스는 늘어나지만 유연성을 향상시키기 위한 비용으로 생각하자 실제로 클라이언트에게 노출되는 클래스의 개수가 중요하다 - 인터페이스를 추상 클래스로 만들어도 되는지 공통된 기능이 있다면 써도 좋다
  • 19. 당첨 기능 추가 코드 변경을 해야하는 부분이 줄었다
  • 20. QUIZ - 바꿔 쓸 수 있는 행동을 캡슐화 한 다음, 실제 행동은 다른 객체에게 위임한다 - 알고리즘의 각 단계를 구현하는 방법을 서브 클래스에서 구현한다 - 상태를 기반으로 하는 행동을 캡슐화 하고 행동을 현재 상태한테 위임한다 스테이트 스트레티지 템플릿 메소드
  • 21. QUIZ - 바꿔 쓸 수 있는 행동을 캡슐화 한 다음, 실제 행동은 다른 객체에게 위임한다 -> 스트레티지 패턴 - 알고리즘의 각 단계를 구현하는 방법을 서브 클래스에서 구현한다 -> 템플릿 메소드 패턴 - 상태를 기반으로 하는 행동을 캡슐화 하고 행동을 현재 상태한테 위임한다 -> 스테이트 패턴
  • 22. 핵심 정리 - 스테이트 패턴을 이용하면 내부 상태를 바탕으로 여러 가지 서로 다른 행동을 사용할 수 있다 - 스테이트 패턴을 사용하면 프로시저 형 상태 기계를 쓸 때와는 달리 각 상태를 클래스를 이용하여 표현하게 된다 - Context 객체에서는 현재 상태에게 행동을 위임한다 - 각 상태를 클래스로 캡슐화 함으로써 나중에 변경시켜야 하는 내용을 국지화 시킬 수 있다 - 스테이트 패턴과 스트래티지 패턴의 클래스 다이어그램은 똑같지만 그 용도는 서로 다르다
  • 23. 핵심 정리 - 스트레티지 패턴에서는 일반적으로 행동 또는 알고리즘을 Context 클래스를 만들 때 설정한다 - 스테이트 패턴을 이용하면 Context의 내부 상태가 바뀜에 따라 알아서 행동을 바꿀 수 있도록 할 수 있다 - 상태 전환은 State 클래스에 의해서 제어할 수도 있고 Context 클래스에 의해서 제어 할 수도 있다 - 스테이트 패턴을 이용하면 보통 디자인에 필요한 클래스의 개수가 늘어난다 - State 클래스를 여러 Context 객체의 인스턴스에서 공유하도록 디자인 할 수 있다