* State Pattern
State Pattern : 어떤 상태를 클래스로 표현해 객체로 다룰 수 있는 패턴.
많은 상태가 있고 각 상태마다 다양한 처리를 해야 하는 경우 if 조건문이 많아지는데, 이를 효과적으로 줄여주는 패턴.
4개의 상태가 있고, 상태를 변화시킬 때마다 출력하는 문구가 다른 경우 총 16개의 if 조건문을 사용해 각 상태 변화에 따른 출력 문구를 정해야 한다.
이때 State Pattern을 사용하면 4개의 State 객체를 생성해 이를 처리할 수 있다.
Player : 4가지 상태를 필드에 가질 수 있음. 이를 통해 자신의 상태를 정할 수 있음.
State : 각 상태를 하나로 묶는 추상 클래스.
StandUpState, SitDownState, WalkState, RunState : 각 이름의 상태를 구현한 클래스.

상태를 가지고 있는 Player
public class Player {
private int speed;
public void setSpeed(int speed) {
this.speed = speed;
}
public int getSpeed() {
return speed;
}
private State state = new StandUpState(this); // 현재 상태
public void setState(State state) {
this.state = state;
}
public State getState() {
return state;
}
public void talk(Steing msg) {
System.out.println("플레이어의 말: \"" + msg + "\"");
}
}
State 인터페이스
public abstract class State {
protected Player player;
public State(Player player) {
this.player = player;
}
public abstract void standUp();
public abstract void sitDown();
public abstract void walk();
public abstract void run();
public abstract void getDescription();
}
각 상태들 구현
- StandUpState
public class StandUpState extend State {
public StandUpState(Player player) {
super(player);
}
@Override
public void standUp() {
player.talk("언제 움직일꺼야?");
}
@Override
public void sitDown() {
player.setState(new SitDownState(player));
player.talk("앉으니깐 편하고 좋습니다.");
}
@Override
public void walk() {
player.setSpeed(5);
player.setState(new WalkState(player));
player.talk("걷기는 제2의 생각하기다..");
}
@Override
public void run() {
player.setSpeed(10);
player.setState(new ReunState(player));
player.talk("갑자기 뛴다!");
}
@Override
public String getDescription() {
return "제자리에 서 있음";
}
}
- SitDownState
public class SitDownState extend State {
public SitDownState(Player player) {
super(player);
}
@Override
public void standUp() {
player.setState(new StandUpState(player));
player.talk("인나자..");
}
@Override
public void sitDown() {
player.talk("쥐나겠다..");
}
@Override
public void walk() {
player.setState(new StandUpState(player));
player.talk("앉아서 어떻게 걸어? 일단 서자..");
}
@Override
public void run() {
player.setState(new StandUpState(player));
player.talk("앉아서 어떻게 뛰어? 일단 서자..");
}
@Override
public String getDescription() {
return "앉아있음";
}
}
- WalkState
public class WalkState extend State {
public WalkState(Player player) {
super(player);
}
@Override
public void standUp() {
player.setSpeed(0);
player.talk("멈춰...");
player.setState(new StandUpState(player));
}
@Override
public void sitDown() {
player.setSpeed(0);
player.talk("걷다가 앉으면 넘어질 수 있어요..");
player.setState(new SitDownState(player));
}
@Override
public void walk() {
player.talk("난 걷는걸 좋아하지..");
}
@Override
public void run() {
player.setSpeed(20);
player.talk("걷다가 뛰면 열라 빨리 뛸 수 있지!");
player.setState(new ReunState(player));
}
@Override
public String getDescription() {
return "걷는 중";
}
}
- RunState
public class RunState extend State {
public RunState(Player player) {
super(player);
}
@Override
public void standUp() {
player.setSpeed(0);
player.talk("뛰다가 갑자기 서면 무릎 연골 나가요...");
player.setState(new StandUpState(player));
}
@Override
public void sitDown() {
player.setSpeed(0);
player.talk("뛰가다 앉으라고???");
player.setState(new StandUpState(player));
}
@Override
public void walk() {
player.setSpeed(8);
player.talk("속도를 줄일꼐요~");
player.setState(new WalkState(player));
}
@Override
public void run() {
player.setSpeed(player.getSpeed() + 2);
player.talk("더 빨리 뛰라는 얘기지?");
}
@Override
public String getDescription() {
return "뛰는 중";
}
}
지금까지 작성한 클래스 활용하기.
public class MainEntry {
public static void main(String[] args) {
plater plater = new Player();
Scanner scanner = new Scanner(System.in);
while(true) {
System.out.println("플레이어의 상태: "
+ player.getState().getDescription()
+ " / 속도: " + player.getSpeed() + "km/h");
System.out.print("[1]제자리 서기, [2]앉기, [3]걷기, [4]뛰기, [5]종료: ");
String input = scanner.next();
System.out.println();
if(input.equals("1")) player.getState().standUp();
else if(input.equals("2")) player.getState().sitDown();
else if(input.equals("3")) player.getState().walk();
else if(input.equals("4")) player.getState().run();
else if(input.equals("5")) break;
}
scanner.close();
}
}
'코딩 > Software Architecture' 카테고리의 다른 글
| [GoF Design Pattern] Abstract Factory (0) | 2022.12.24 |
|---|---|
| [Design Pattern] GRASP Pattern (0) | 2022.12.10 |
| [GoF Design Pattern] Chain of Responsibility (0) | 2022.12.06 |
| [GoF Design Pattern] Mediator (0) | 2022.12.06 |
| [GoF Design Pattern] Decorator (0) | 2022.12.05 |