OOP/Design Pattern

[OOP] 상태 패턴(State Pattern)

IT록흐 2022. 11. 13. 22:03
반응형

 

디자인 패턴이란?

객체지향설계 과정에서 발생하는 문제들을 해결하기 위한 패턴(Pattern)

 

문제 상황

 

 

 

전등(Light)이 하나 있다. 상태는 ON, OFF 두 가지 상태가 있다. 그렇다면 ON버튼이 눌려졌을 때는 두 가지 상황이 있다. 

 

onButtonPushed()가 호출되었을 때

-LightOn 상태라면? (조건문)
-LightOff 상태라면? (조건문)

 

반대로 OFF버튼이 눌려졌을 때도 두 가지 상황이 있다. 

 

offButtonPushed()가 호출되었을 때

-LightOn 상태라면? (조건문)
-LightOff 상태라면? (조건문)

 

 
이처럼 상태가 두 가지일 때, 4가지 경우가 생긴단. 여기에 상태가 하나 더 추가되면 어떻게 될까? 대기(Sleeping) 상태를 추가해보자.
 

onButtonPushed()가 호출되었을 때

-LightOn 상태라면? (조건문)
-LightOff 상태라면? (조건문)

+ LightSleeping(대기) 상태라면? (조건문)

 

offButtonPushed()가 호출되었을 때

-LightOn 상태라면? (조건문)
-LightOff 상태라면? (조건문)

+ LightSleeping(대기) 상태라면? (조건문)

 

상태가 하나 더 추가되자 각 메소드의 조건문도 하나씩 추가되었다. 이로인해 메소드의 경우의 수는 복잡해지고 이에 따라 유지보수과정도 복잡해진다. 이처럼 특정 객체와 그 객체의 상태를 결합시키면 상태에 따른 다양한 경우의 수를 하나의 클래스 안에 모두 구현해야 한다. 

 

해결책

 

 

Light객체와 Light의 상태를 인터페이스를 이용하여 분리한다. 그리고 각 상태는 setter함수를 이용하여 Light와 결합한다. 상태에 따른 행동 로직은 각 상태 클래스 안에 구현되어있다. Light는 해당 상태를 setter 함수로 결합만 하면 된다. setter함수로 결합되다보니 다른 상태를 결합하려고 해도 Light클래스의 로직은 수정되지 않아도 된다. 
 
 

코드

Light 클래스

// Light 클래스 ( 부모 클래스 )
public class Light {

    private State state;

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

    public void onButtonPushed() {
        state.onButtonPushed(); // 행위 수행 권한을 위임
    }

    public void offButtonPushed() {
        state.offButtonPushed(); // 행위 수행 권한을 위임
    }
}

 

Main 클래스

public class Main() {
	public static void main(String[] args) {
		
		Light light = new Light();
		
		light.setState(new On(light)); // ON 상태
		light.onButtonPushed(); // ON 버튼 누름
	}
}
 

 

정리

장점 1)

상태가 바뀔 시, 다른 구현객체를 setter함수에 넣어주면 된다.

 

장점 2)

버튼 로직 변경 시,

행위 수행 권한을 위임받은 상태클래스만 변경하면 된다.

 

장점 3)

상태가 추가되어도,

새로운 상태 구현 클래스를 만들어 모든 Light에 적용할 수 있다.

 

 

 


 

 

참고자료

 

JAVA 객체지향 디자인 패턴 : 네이버 도서

네이버 도서 상세정보를 제공합니다.

search.shopping.naver.com

 

 
 

 

반응형