[디자인 패턴] State 패턴

이멀젼씨

·

2020. 3. 24. 11:04

- 정의

 

객체 내부의 상태에 따라 다른 행동을 취할 수 있게 해주는 패턴이다

 

- UML

1. State인터페이스안에 두 가지 sitDown과 getUp메소드를 정의함

2. SittingPerson과 StadingPerson은 State인터페이스를 구현하여 getUP과 sitDown메소드를 오버라이딩함

3. Person클래스는 setState를 통해 상태를 설정하고, getUp과 sitDown을 통해 행위를 수행하도록 함

 

- 코드

 

State interface

public interface State {
	public void sitDown(Person person);
	public void getUp(Person person);
}

 

SittingPerson class

public class SittingPerson implements State{
	
	@Override
	public void getUp(Person person) {
		System.out.println("일어났습니다");
		person.setState(this);
	}
	
	@Override
	public void sitDown(Person person) {
		System.out.println("이미 앉아있습니다");
		person.setState(this);
	}
}

 

StandingPerson class

public class StandingPerson implements State{
	
	@Override
	public void getUp(Person person) {
		System.out.println("이미 일어서있습니다");
		person.setState(this);
	}
	
	@Override
	public void sitDown(Person person) {
		System.out.println("앉았습니다");
		person.setState(this);
	}
}

 

 

Person class

public class Person {
	private State state;
	
	public void setState(State state) {
		this.state = state;
	}
	
	public void getUP() {
		state.getUp(this);
	}
	
	public void sitDown() {
		state.sitDown(this);
	}
}

Main class

public class Main {
	public static void main(String[] args) {
		Person person = new Person();
		person.setState(new SittingPerson());
		
		person.sitDown();
		person.getUP();
		
		person.setState(new StandingPerson());
		
		person.getUP();
		person.sitDown();
	}
}

출력결과

이미 앉아있습니다
일어났습니다
이미 일어서있습니다
앉았습니다

 

- 설명

 

Person클래스의 인스턴스를 생성하고 현재 상태를 설정해준다

 

현재 상태는 setState(new SittingPerson())을 통해 앉아있는 상태임을 알 수 있다

 

앉아있는 상태에서 sitDown을 하게 되면 이미 앉아있습니다라는 문장이 나오고, getUp을 하면 일어났습니다가 나오게 된다

 

현재 상태를 StandingPerson으로 바꾼 뒤 getUp을 하면 이미 일어나 있습니다라는 문장이 나오고, sitDown을 하면 앉았습니다라는 문장이 나온다

 

즉 현재 상태에 따라 다른 행동이 나오는 것을 알 수 있다

 

2020/01/14 - [Java/디자인패턴] - [디자인 패턴] Strategy 패턴

 

[디자인 패턴] Strategy 패턴

- 정의 여러 전략들에 대한 하나의 인터페이스를 만들어 각 접근점에서 서로 교환이 가능하도록 하는 패턴이다. 간단하게 설명하자면, 인터페이스를 정의한 뒤 인터페이스를 따르는 여러 전략을 생성하고 필요시에..

emgc.tistory.com

State패턴은 Strategy패턴과 굉장히 유사하다

 

Strategy패턴을 사용하면 Context클래스(Study클래스)는 일(알고리즘)으로부터 자유로워진다

Study클래스는 단지 doStudy메소드 하나만을 호출하면 될 뿐이고, doStudy에 해당하는 상세한 내용은 알 필요가 없게 된다

doStudy에 해당하는 복잡한 내용들은 StudyStrategy인터페이스를 구현하는 클래스에서 오버라이딩하여 메소드를 구현하기 때문이다.

Strategy인터페이스를 구현하는 새로운 Strategy클래스를 만듦으로써 새로운 일(알고리즘)을 하도록 만들 수 있다

 

State패턴을 사용하면 현재 어떤 상태인지를 검사할 필요가 없게된다

즉 상태가 1일 때 뭐는 되고 뭐는 안되고, 0일 때는 뭐는 되고 뭐는 안되고 등 if문을 사용하여 상태를 체크할 필요가 없다

Person클래스는 단지 SittingPerson과 StandingPerson을 통해 상태를 설정해주기만 하고 실행하는 메소드는 설정된 상태에 따라 알아서 실행되게 된다 

 

Strategy패턴 - 하는 행동을 동일하나 그 행동의 알고리즘이 다양할 때 사용

State패턴 - 상태에 따른 행동이 독립적일 경우(Sitting상태에서 앉을 때 '이미 앉아있습니다'와 같은 경우) 사용