본문 바로가기
IT 공부/디자인패턴

[디자인패턴] State Pattern 상태패턴

by 쭈잇 2019. 5. 2.

Contents

    반응형

    상태 패턴이란?

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

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


    왜 사용하는가?

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

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

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


     

     

    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 변수는 오직 행위를 변경하고자 하는 목적에서 선언 된 것!


    수정 )

     

    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

    반응형