Java/Java 객체지향 디자인 패턴

[Java 객체 지향 디자인 패턴] 7. 스테이트 패턴 - State Pattern : 상태의 캡슐화

디벨로펄 2022. 3. 14.
반응형

상태란 객체가 시스템에 존재하는 동안, 즉 객체의 라이프 타임 동안 객체가 가질 수 있는 어떤 조건이나 상황을 표현한다. 

 

스테이트 패턴

스테이트 패턴은 상태에 따라 동일한 작업이 다른 방식으로 실행될 때 해당 상태가 작업을 수행하도록 위임하는 디자인 패턴이다.

 

스테이트 패턴의 목표는 현재 시스템이 어떤 상태에 있는지와 상관없이 구성하고, 상태변화에도 독립적이도록 코드를 구현하는 것이다. 이를 위해서 상태를 클래스로 분리해 캡슐화 한다.

 

 

스테이트 패턴으로 구현한 형광등 상태 머신 다이어그램

Light(형광등)은 State를 attribute로 가지고 있으며, 외부에서 의존성을 주입 받기 위해 setState Method까지 가지고 있다. State Interface를 구현한 형광등의 상태인 ON, OFF가 있으며, 각 상태에서 on, off를 실행하는 코드를 작성해준다.

 

 

public interface State {
	public void on_button_pushed(Light light);

	public void off_button_pushed(Light light);
}
public class ON implements State {

	@Override
	public void on_button_pushed(Light light) {
		System.out.println("반응 없음"); // 켜진상태에서는 on을 눌러도 아무 행동이 일어나면 안되겠지.

	}

	@Override
	public void off_button_pushed(Light light) {
		System.out.println("Light Off");
		light.setState(new OFF());

	}

}
public class OFF implements State {

	@Override
	public void on_button_pushed(Light light) {
		System.out.println("Light Off");
		light.setState(new ON());
	}

	@Override
	public void off_button_pushed(Light light) {

		System.out.println("반응 없음");
	}

}

Light코드만 봐도 어떤 행동을 하는지 쉽게 알 수 있고, 각 상태에 대한 처리를 상태 클래스에서 처리하기 때문에 훨씬 간단하게 코딩할 수 있다. 실제로 작성해보니 진짜 편한걸 알겠다..ㄷ.ㄷ 상태가 새로운 상태로 교체되어도 Light클래스는 전혀 영향을 받지 않는 것을 확인할 수 있다.

public class Light {
	private State state;

	public Light() {
		state = new OFF();

	}

	public void setState(State state) {
		this.state = state;
	}

	public void on_button_pushed() {
		state.on_button_pushed(this);
	}

	public void off_button_pushed() {
		state.off_button_pushed(this);
	}
}

 

스테이트 패턴 설명

 

스테이트 패턴 컬레보레이션

- State : 시스템의 모든 상태에 공통의 인터페이스를 제공한다. 따라서 이 인터페이스를 실체화한 어떤 상태 클래스도 기존 상태 클래스를 대신해 교체해서 사용할 수 있다.

- State1, State2, State3 : Context 객체가 요청한 작업을 자신의 방식으로 실제 실행한다. 대부분의 경우 다음 상태를 결정해 상태 변경을 Context 객체에 요청하는 역할도 수행한다. 

- Context : State를 이용하는 역할 수행. 현재 시스템의 상태를 나타내는 상태 변수와 실제 시스템의 상태를 구성하는 여러 변수가 있다. 그리고, 각 상태 클래스에서 상태 변경을 요청해 상태를 바꿀 수 있도록 하는 setState메서드가 제공된다. Context 요소를 구현한 클래스의 request메서드는 실제 행위를 실행하는 대신 해당 상태 객체에 행위 실행을 위임한다.

 

 


연습문제

1. 스테이트 패턴 vs 스트래티지 패턴

구조적인 면에서는 상당히 비슷하다. 스테이트 패턴은 상태를 캡슐화한 것이고, 스트래티지 패턴은 전략을 캡슐화한 것이다. ...?

 

2. 선풍기의 상태 머신 다이어그램

 

3. 코드 7-5 참고, 취침등 상태를 추가한 Light 클래스 완성.  --> Light클래스는 손대지 않고, SLEEPING state만 추가하면 된다.. 오우.. 엄청나..

 

5. 벤딩머신을 스테이트 패턴을 활용해 작성.

연습문제의 해설과 가장큰 차이점은 VendingMachine에서 Drinking 객체와 MoneyBox 객체를 따로 설계하고, 이를 Attribute으로 사용한다는 점이다. 나는 음료 가격과 재고, 투여된 금액을 String, int형으로 저장을 했었다. 

 

https://github.com/dhdnjswnd/JavaObjectiveDesignPattern/tree/main/src/chapter7_statepattern

 

GitHub - dhdnjswnd/JavaObjectiveDesignPattern: 자바 객체지향 디자인패턴 공부자료

자바 객체지향 디자인패턴 공부자료. Contribute to dhdnjswnd/JavaObjectiveDesignPattern development by creating an account on GitHub.

github.com

 

 

공부하는 책

 

JAVA 객체지향 디자인 패턴 - 교보문고

UML과 GoF 디자인 패턴 핵심 10가지로 배우는 | 이 책이 제시하는 핵심 내용객체지향 이론과 UML을 통해 GoF 디자인 패턴의 핵심 10가지를 배운다.이 책의 특징과 장점5단계 학습법으로 디자인 패턴을

www.kyobobook.co.kr

 

반응형

댓글