상태 패턴(State Pattern)
상태 패턴은 특정 상태마다 다르게 할 일을 정의하고 나아가 상태 자체를 객체화하는 디자인 패턴이다. 가장 쉬운 예시는 TV이다. TV는 ON/OFF 버튼으로 ON 상태, OFF 상태로 변환한다.
예시
컴퓨터의 전원 버튼을 누르면 전원이 켜지고, 켜진 상태에서 다시 전원 버튼을 누르면 컴퓨터를 종료할 수 있다.
public class Computer {
public static String ON = "on";
public static String OFF = "off";
private String state = "";
public Computer(){
setState(Laptop.OFF);
}
public void setState(String state){
this.state = state;
}
public void pushBtn(){
if ("on".equals(this.state)) {
System.out.println("전원 off");
}
else {
System.out.println("전원 on");
}
}
}
위 상태를 기본으로하고 절전 모드 기능이 추가되었다고 가정하자.
- 전원이 꺼진 상태, 버튼 누를 시 절전(saving) 모드
- 절전 모드 상태, 버튼 누를 시 전원이 켜지는 on 상태
- 전원이 켜진 상태, 버튼 누를시 전원이 꺼지는 off 상태
public class Computer {
public static String ON = "on";
public static String OFF = "off";
public static String SAVING = "saving";
private String state = "";
public Computer(){
setState(Laptop.OFF);
}
public void setState(String state){
this.state = state;
}
public void pushBtn(){
if ("on".equals(state)) {
System.out.println("전원 off");
}
else if("off".equals(state)){
System.out.println("절전 모드");
}
else {
System.out.println("전원 on");
}
}
}
단순히 보면 조건문만 한 줄 추가했지만 만약에 상태가 여러개가 존재할 경우 상태마다 하고자 하는 행위를 파악하기 어려워진다.
코드 개선
상태 구현
interface State{
fun pushBtn(computer:Computer)
}
class On : State{
companion object {
val on = On()
}
fun getInstance() = on
override fun pushBtn(computer:Computer){
print("전원 off")
computer.setState(Off.getInstance())
}
}
class Off : State{
companion object {
val off= Off()
}
fun getInstance() = off
override fun pushBtn(computer:Computer){
print("절전 모드")
computer.setState(Saving.getInstance())
}
}
class Saving : State{
companion object {
val saving = Saving()
}
fun getInstance() = saving
override fun pushBtn(computer:Computer){
print("전원 on")
computer.setState(On.getInstance())
}
}
위의 companion object와 getInstance는 매번 새로운 객체를 생성하여 메모리 낭비하는 것을 방지하기 위함이다.
컴퓨터 구현
class Computer(private var state:State){
init{
state = Off()
}
fun setState(state: State){
this.state=state
}
fun pushBtn(){
state.pushBtn(this)
}
}
이렇게 구현하게 된다면, 클라이언트에서는 pushBtn() 메서드만 호출하면 상태에 맞게 알아서 동작하게 된다.
전략 패턴 vs 상태 패턴
- 전략 패턴: 컨텍스트가 실행할 객체를 외부 객체(클라이언트)에서 지정해준다.
- 상태 패턴:외부 객체(클라이언트)의 개입 없이 상태 객체 내부에서 현재 상태에 따라 컨텍스트의 상태가 변경된다.
요약
- 상태패턴은 상태 별로 객체화하여 상태가 행위를 하는 패턴
'Domain > 디자인패턴' 카테고리의 다른 글
[디자인패턴] 퍼사드 패턴(Facade Pattern) (0) | 2021.03.30 |
---|---|
[디자인패턴] 템플릿 메소드 패턴(Template Method Pattern) (0) | 2021.03.30 |
[디자인패턴] 어댑터 패턴(Adapter Pattern) (0) | 2021.03.28 |
[디자인패턴] 전략 패턴(Strategy Pattern) (0) | 2021.03.28 |
[디자인패턴] 팩토리 패턴(Factory Pattern) (0) | 2021.03.27 |