State

1 minute read

> 상태 패턴이란?

객체가 특정 상태에 따라 행위를 달리하는 상황 (-> 상태 변수에 따라 변수와 행위의 결합을 만들어 내는 것)

에서 자신이 직접 상태를 체크하여 상태에 따라 행위를 호출하지 않고, 상태를 객체화하여 상태가 행동을 할 수 있도록 위임하는 패턴


> 왜 사용하는가?

- 상태 변수에 의해 행위가 변경됨

- 이 상태 변수가 행위를 변경하기 위해 조건문을 사용함

- 상태 변수를 체크하기 위한 조건문이 너무 많음


img

Context : 여러가지 내부 상태를 가질 수 있는 클래스/ request()가 호출되면 상태 객체에게 그 작업을 위임

State : 모든 구상 상태클래스에 대한 공통 인터페이스 정의

ConcreateState : context 로 부터 전달된 요청을 처리하는 구상 상태클래스. (자기 방식으로 구현)


예)

public class Employee {
    public static final int ENGINEER=1;
    public static final int MANAGER=2;
    public static final int SALESMAN=3;
    private int type;
    public void setType(int type) {
        this.type=type;
    }
    public Employee(int type) {
        setType(type);
    }

    public int getAmount() {
        switch (type) {
        case ENGINEER:
            return 100;
        case MANAGER:
            return 100;
        case SALESMAN:
            return 100;
        }
        return 0;
    }
}
public class Main {
public static void main(String[] args) {
	Employee2 e=new Employee2(new Salesman());
	int money=e.getAmount();
	System.out.println(money);
}
}
>> 결과값 : 300

> Employee 객체는 직원의 타입을 나타내기 위해 내부적으로 type이라는 상태 변수를 사용

> type 변수는 switch-case 의 각 구문과 1:1 매칭이 됨.

> type 변수는 값에 따라서 다른 구문이 호출.

type 변수는 오직 행위를 변경하고자 하는 목적에서 선언 된 것!


수정 )

img

public interface EmployeeType {
    public int getAmount();
}
public class Enginner implements EmployeeType{

    @Override
    public int getAmount() {
        return 100;
    }

}
public class Manager implements EmployeeType{

    @Override
    public int getAmount() {
        return 200;
    }

}
public class Salesman implements EmployeeType{

    @Override
    public int getAmount() {
        return 300;
    }

}
public class Employee2 {
    private EmployeeType type;
    public void setType(EmployeeType type) {
        this.type=type;
    }
    public Employee2(EmployeeType type) {
        setType(type);
    }

    public int getAmount() {
        return type.getAmount();
    }
}

스테이트 패턴은 상태를 별도의 클래스로 캡슐화한 다음, 현재 상태를 나타내는 객체에게 행동을 위임한다. 따라서 내부 상태가 바뀌면 행동이 달라지게 된다 (if, switch문과 같은 분기문을 패턴을 이용해 캡슐화, 분리화한다고 생각하면 됨!!)

-> 다른 클래스로 변신하는 것이 아니라 구성을 통해 여러 상태 객체를 바꿔가면서 사용


> 장점

  1. 각 상태의 행동을 클래스로 나눔 - 캡슐화

  2. 관리하기 힘든 if선언문 없앰(switch, if-else) - 유연성

  3. 각 상태를 변경에 대해서는 닫혀있고, 새로운 클래스를 추가하는 확장에 대해서는 열려있음 OCP

[참고]

https://plposer.tistory.com/30

https://effectiveprogramming.tistory.com/entry/State-%ED%8C%A8%ED%84%B4

https://sticky32.tistory.com/entry/%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-%EC%8A%A4%ED%85%8C%EC%9D%B4%ED%8A%B8-%ED%8C%A8%ED%84%B4State-Pattern

Updated: