본문 바로가기
Design Pattern

19. 상태 패턴 ( state pattern)

by 킹차니 2021. 12. 31.

상태 패턴

객체 내부 상태 변경에 따라 객체의 행동이 달라지는 패턴

--> 상태에 특화된 행동들을 분리해 낼 수 있으며, 새로운 행동을 추가하더라도 다른 행동에 영향을 주지 않는다.

 

예로 티비가 켜져있다면 음량버튼을 누르면 음량이 증가하거나 감소한다. 하지만 전원버튼을 눌러 티비를 끈다면 음량버튼을 아무리 눌러도 티비의 음량은 바뀌지 않는다. 즉 티비전원이 눌렸나? 안눌렸나? 라는 리모컨의 상태에 따라 행동이 바뀌는 것이다.

 


코드로 알아보기

 

온라인강의가 있고, 이것을 학생들이 수강할 수 있다고 하자. 온라인강의에 학생을 추가하거나, 리뷰를 달 수 있는데, 이때 온라인 강의의 상태에 따라 학생 추가와 리뷰 달기가 다르게 작동한다. 먼저 클라이언트 코드를 보자.

 

OnlineCourse는 아래와 같다.

OnlineCourse의 addReview메소드롸 addStudent메소드를 보면 if문으로 인해 로직들이 꽤나 복잡하고, 쉽게 읽히지 않는다. 여기에 상태 패턴을 적용하여 보자.

 

먼저 State 인터페이스를 정의해야 한다 위의 패턴 적용 전 코드에서 addStudent와 addReview메소드 때문에 복잡한 코드가 되었다. 이러한 메소드들을 인터페이스에 정의한다.

그리고 OnlineCourse의 state는 총 3가지가 있었다. 하여 각각의 PRIVATE, PUBLISHED, DRAFT 상태에서의 로직을 각각에 구현하면 된다. 

예로 addStudent()에서 if(state == State.DRAFT || state == State.PUBLISHED)라면 바로 학생을 추가한다. 하여 Draft를 구현할 시에는 addStudent()에서 바로 students에 student를 추가한다. 이제 각 State 클래스들을 보자.

 

 

Draft

 

Private

 

Publisher

 

이제 OnlineCourse



이때 특히 OnlineCourse는 상태에 따라 다른 동작을 취하기 위해 State를 참조해야한다.

 

 

Student는 아래와 같다.

 

이제 Client코드를 보자.

먼저 Private상태일 때의 결과 :

 

 

다음으로 Published일 때

실행결과:

 

마지막으로 Draft일 때

실행결과:

익셉션이 발생한다.

 

 

 


장점과 단점

 

장점

1. 상태에 따른 동작을 개별 클래스로 옮겨서 관리할 수 있다. (가장 큰 장점)

2. 기존의 특정 상태에 따른 동작을 변경하지 않고 새로운 상태에 다른 동작을 추가할 수 있다.

3. 코드 복잡도를 줄일 수 있다.

 

단점

클래스가 많아지면서  복잡도가 증가한다.

 

 

출처: 인프런 백기선님 '코딩으로 학습하는 GoF 강의'
https://www.inflearn.com/course/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4