티스토리 뷰

Programing/DesignPattern

State 패턴

오통 2016. 9. 1. 17:18

State 패턴이란?


- 객체의 상태에 따라 바뀌는 행위를 캡슐화 한 패턴.

- 상태에 따라 if, else 조건문으로 분기하는 부분을 제거하여 simple한 코드를 구성할 수 있다.


 

예제


강아지 육성 프로그램(다마고치)을 만들어보자.

사용자는 강아지에게 밥을 주거나, 놀아주는 2가지 행위를 할 수 있다.

그리고 강아지는 GOOD, HUNGRY, BORED 3가지 상태를 가지고, 상태에 따른 다른 행동을 한다.


- GOOD : 배고프지도, 심심하지도 않은 상태.

- HUNGRY : 배고픈 상태

- BORED : 심심한 상태



public class Damagochi {
    private static final int GOOD = 0;    // 좋은 상태
    private static final int HUNGRY = 1;     // 배고픈 상태
    private static final int BORED = 2;    // 심심한상태
	
    private int state = GOOD;  

    // 현재 상태를 저장.
    public void setState(int state) {
        this.state = state;
    }
	
    // eat action에 대한 상태별 행위
    public void eat() {
	if (state == HUNGRY) {
	    System.out.println("맛있다 오예^^");    // 배고플 때는 맛있게 먹음. GOOD으로 상태 변경
	    setState(GOOD);
	} else if (state == GOOD) {
	    System.out.println("점점 심심해져요...");    // 배부를 때는 심심해짐. BORED로 상태 변경
	    setState(BORED);
	} else if (state == BORED) {    // 지루할 때는 놀아다라고 요청. 상태변경 없음.
	    System.out.println("놀아주세요ㅠㅠ");
	}
    }
	
    // play action에 대한 상태별 행위
    public void play() {
	if (state == BORED) {    // 지루할 때는 신나함. GOOD으로 상태 변경
            System.out.println("신난다 오예^^");
	    setState(GOOD);			
	} else if (state == GOOD) {
	    System.out.println("점점 배고파 져요...");    // 심심하지 않을 때는 배고파짐. HUNGRY로 상태 변경
	    setState(HUNGRY);
	} else if (state == HUNGRY) {
	    System.out.println("밥 주세요ㅠㅠ");    // 배고플 때는 밥달라고 요청. 상태변경 없음.
	}
    }
}


문제점

- 상태에 따른 조건문이 많아서 code 가독성이 떨어지고 복잡함.

- 상태가 많아지거나 eat(), play() 외의 기능 추가 될 수록 조건문 추가 되므로 복잡해 지고 유지보수에 어려움이 있음.


state 패턴을 적용하여 상태를 class로 바꿔 보자.


public class Damagochi {
    // 각각의 Status class
    private GoodState goodState;
    private HungryState hungryState;
    private BoredState boredState;
	
    private State currentState;

    public Damagochi() {
        goodState = new GoodState(this);
	hungryState = new HungryState(this);
	boredState = new BoredState(this);
	// 초기 State는 GOOD
	currentState = goodState;
    }
	
    public void setState(State state) {
 	this.currentState = state; 
    }
	
    public State getGoodState() {
 	return goodState;
    }
	
    public State getHungryState() {
  	return hungryState;
    }
	
    public State getBoredState() {
  	return boredState;
    }
	
    // eat action에 대한 행위를 현재 State에게 위임
    public void eat() {
  	currentState.eat();
     }

    // play action에 대한 행위를 현재 State에게 위임.
    public void play() {
 	currentState.play();
    }
}

public abstract class State {
    public Damagochi context;
	
    public State(Damagochi context) {
  	this.context = context;
    }
	
    abstract void eat();
    abstract void play();
}

public class GoodState extends State{

    public GoodState(Damagochi context) {
	super(context);
    }

    @Override
    void eat() {
	System.out.println("점점 심심해져요...");
	context.setState(context.getBoredState());
    }

    @Override
    void play() {
 	System.out.println("점점 배고파져요...");
	context.setState(context.getHungryState());
    }
}

public class HungryState extends State{

    public HungryState(Damagochi context) {
 	super(context);
    }

    @Override
    void eat() {
	System.out.println("맛있다 오예^^");
	context.setState(context.getGoodState());
    }

    @Override
    void play() {
	System.out.println("밥 주세요ㅠㅠ");
    }
}

public class BoredState extends State{

    public BoredState(Damagochi context) {
 	super(context);
    }

    @Override
    void eat() {
   	System.out.println("놀아주세요ㅠㅠ");
    }

    @Override
    void play() {
	System.out.println("신난다. 오예^^");
	context.setState(context.getGoodState());
    }
}


위 처럼 구현 시, 기존 Damagochi class (Context)의 조건문이 모두 사라지고, 각각의 State 객체에게 행위를 위임하고 있다.

상태가 추가되더라도 상태클래스를 추가하여 해당 상태에 맞는 구현을 code를 구현하면 된다.


'Programing > DesignPattern' 카테고리의 다른 글

Factory Method 패턴  (0) 2016.10.05
GOF 디자인 패턴  (0) 2016.10.04
Template Method 패턴  (0) 2016.08.30
Composite 패턴  (0) 2016.08.24
Singleton 패턴  (0) 2016.08.24
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함