목표:
서로 다른 State들에 대해 같은 동작을 실행해야 할 때,
이를 긴 if else if 문으로 실행하는 것보다 더 나은 방법을 찾는 것이 state 패턴의 목표이다.
예시 상황:
포토샵과 유사한 프로그램을 구현한다고 가정해보자.
선택한 tool에 따라 mouseDown(), mouseUp()이 실행될 때마다 다른 결과가 도출되어야 한다.
접근1:
if else if 문을 사용한다.
package state;
public class Canvas {
private ToolType currentTool;
public void mouseDown() {
if (currentTool == ToolType.SELECTION) {
System.out.println("Selection MouseDown");
} else if (currentTool == ToolType.BRUSH) {
System.out.println("Brush MouseDown");
} else if (currentTool == ToolType.ERASER) {
System.out.println("Eraser MouseDown");
}
public void mouseUp() {
if (currentTool == ToolType.SELECTION) {
System.out.println("Selection MouseUp");
} else if (currentTool == ToolType.BRUSH) {
System.out.println("Brush MouseUp");
} else if (currentTool == ToolType.ERASER) {
System.out.println("Eraser MouseUp");
}
}
}
코드의 길이가 불필요하게 길어질 뿐더러, 확장성도 좋지 못한 나쁜 접근 방법이다.
접근2 - State 패턴:
객체의 Polymorphism 특성을 이용한다.
서로 다른 State 들을 전부 하나의 부모 클래스를 상속한 자식 클래스들로 표현한다.
package state;
public class Canvas {
private ToolType currentTool;
public void mouseDown() {
currentTool.mouseDown();
}
public void mouseUp() {
currentTool.mouseUp();
}
}
가독성도 좋아질 뿐만 아니라, 새로운 Tool을 추가할 때 Canvas의 코드는 전혀 수정할 필요가 없다.
정리:
State 패턴은 다음 객체들의 협력을 통해 구현된다.
1. 다양한 State를 가질 수 있는 객체. 주로 행동의 주체가 되는 객체이다. (= Context)
2. 다양한 State를 표현할 수 있는 하나의 부모 객체. 추상 클래스(abstract class)나 인터페이스(interface)를 사용하는 게 권장된다. (= State)
3. 부모 객체를 상속 혹은 implement한 State를 나타내는 다양한 객체들. (= ConcreteState)
'software engineering > design patterns' 카테고리의 다른 글
디자인 패턴을 남용하지 말아야 하는 이유 (0) | 2021.01.09 |
---|---|
Memento 패턴 (0) | 2021.01.09 |
UML이란 (0) | 2021.01.09 |