상태 패턴이란, 각 상태를 클래스로 만들고 해당 상태에서 이루어질수 있는 행동을 정의하도록 설계하는 패턴
입니다.
각 상태들을 클래스로 만들어 각 상태에서 이루어지는 행동을 메소드로 정의하고 캡슐화하여 인터페이스를 호출하는 방식으로 이루어집니다.
Laptop을 예시로 들어보겠습니다.
Laptop클래스에서 전원을 켰을때 수행되는 powerOn(), 전원을 껐을때 수행되는 powerOff()메소드가 있습니다.
public class Laptop {
public static String ON = "on";
public static String OFF = "off";
private String powerState = "";
public Laptop(){
setPowerState(Laptop.OFF);
}
public void setPowerState(String powerState){
this.powerState = powerState;
}
public void powerPush(){
if ("on".equals(this.powerState)) {
this.powerOn();
}
else {
this.powerOff();
}
}
public void powerOn(){
System.out.println("전원 off");
}
public void powerOff(){
System.out.println("전원 on");
}
}
위와같이 수행된다면, saving이라는 상태가 새로 추가되었을 경우 powerPush()에 saving상태일때의 분기가 수정되어야합니다.
이는 OOP원칙의 OCP을 위반하게 됩니다.
그렇기 때문에 각 상태에 대해 클래스를 선언하고 객체지향적으로 분기를 처리해 줄 수 있어야합니다.
public interface PowerState{
void powerPush();
}
static public class onState implements PowerState{
public onState(){};
@Override
public void powerPush() {
System.out.println("전원 off");
}
}
static public class offState implements PowerState{
public offState(){}
@Override
public void powerPush() {
System.out.println("전원 saving");
}
}
static public class savingState implements PowerState{
public savingState(){};
@Override
public void powerPush() {
System.out.println("전원 on");
}
}
public class Laptop{
private PowerState powerState;
public Laptop(){
setPowerState(new offState());
}
public void setPowerState(PowerState powerState){
this.powerState = powerState;
}
public void powerPush(){
this.powerState.powerPush();
}
public void powerOn(){
System.out.println("전원 off");
}
public void powerOff(){
System.out.println("전원 on");
}
}
위와 같이 onState, offState, savingState 클래스를 정의하고 캡슐화하여 인터페이스로 정의한다면, Laptop에서 상태 별로 분기를 처리하지 않고 상태별로 행동을 취할 수 있으며, 새로운 상태가 추가되어도 OCP를 위배하지 않습니다.
이렇게 표현할 수 있게됩니다.
정리하자면, 상태 패턴은 상태별 행동에 대해 분기를 처리할때 사용한다
고 이해했습니다.