시그마 삽질==six 시그마

스테이트 패턴(State pattern) 본문

프로그래밍/디자인패턴

스테이트 패턴(State pattern)

Ethan Matthew Hunt 2020. 4. 24. 21:21
'Java 객체 지향 디자인 패턴' 책을 구입하시길  추천드립니다.

책 구입을 원하시는분은 요기를 클릭하시면 됩니다.

하단의 내용은 제가 예전에 읽었던 내용을 요약 정리한 것입니다.

 

The state pattern is a behavioral software design pattern that allows an object to alter its behavior when its internal state changes. This pattern is close to the concept of finite-state machines. The state pattern can be interpreted as a strategy pattern, which is able to switch a strategy through invocations of methods defined in the pattern's interface.

source:https://en.wikipedia.org/wiki/State_pattern

 

https://en.wikipedia.org/wiki/State_pattern

스테이트 패턴은 어떤 행위를 수행할때 상태에 행위를 수행하도록 위임하는 패턴이다.

이를 위해 시스템의 각 상태를 클래스로 분리해 캡슐화하고 각 클래스에서 수행하는 행위들을 메서드로 구현한다.

 

 

 

형광등 클래스

 

다음예제를 살펴보자

 

class Light {
     private static final int ON  = 0;
     private static final int OFF = 1;
     private int state;

     public Light() { state = OFF; }

     public void on_button() {
       if (state == ON) { System.out.println("반응없음!"); }
       else { System.out.println("Light on!!"); state = ON; }
     }

     public void off_button() {
       if (state == OFF) { System.out.println("반응없음!"); }
       else {  state = OFF; }
     }
   }   
   
   
   
public class Client {
 public static void main(String[] args) {
  Light light= new Light();
  light.off_button();
  light.on_button();
  light.off_button();
  }
}

그런데 위에서 취침등 상태가  추가된다면

 

class Light {
     
     private static final int ON  = 0;
     private static final int OFF = 1;
     private static final int SLEEP = 2;  // 추가
     private int state;
     
 

     public Light() { state = OFF; }

     public void on_button() {
       if (state == ON) { System.out.println("취침등 상태!"); state =SLEEP; }
       else if (state == SLEEP) { System.out.println("Light ON!"); state = ON; }
       else { System.out.println("Light ON!"); state = ON; }
     }

     public void off_button() {
       if (state == OFF) { System.out.println("반응없음!"); }
       else if (state == SLEEP) { System.out.println("Light off!"); state = OFF; } 
       else {  System.out.println("Light off!"); state = OFF; }
     }
   } 

 

클래스 내용을 수정함으로써 OCP 위반에 변화 파악이 용이하지 않고 새로운 상태 추가시 상태 변화를 초래하는 모든 메서드에 이를 반영하기 위해 코드를 수정한다

 

위 문제 해결을 위해 상태를 클래스로 분리해 캡슐화한다

 

    class Light {
        private State state;

        public Light() {
            state = OFF.getInstance();
        }

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

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

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


    interface State {
        public void on_button(Light light);
        public void off_button(Light light);
    }

    class ON implements State {

        private static On on =new On();
        private ON(){}
        public static ON getInstance(){
            return on;
        }

        @Override
        public void on_button(Light light) {
            System.out.println("취침등 상태!");
        }
        @Override
        public void off_button(Light light) {
            System.out.println("Light off!");
            light.setState( OFF.getInstance() );
        }
    }

    class OFF implements State {

        private static Off off =new Off();
        private OFF(){}
        public static OFF getInstance(){
            return off;
        }

        @Override
        public void on_button(Light light) {
            System.out.println("Light on!");
            light.setState( ON.getInstance() );
        }
        @Override
        public void off_button(Light light) {
            System.out.println("반응 없음!");
        }
    }



    class SLEEP implements State {
        private static SLEEP instance = new SLEEP();
        public static SLEEP getInstance() {
            return instance;
        }

        @Override
        public void on_button(Light light) {
            System.out.println("Light On Back!");
            light.setState(ON.getInstance());
        }
        @Override
        public void off_button(Light light) {
            System.out.println("Light Off Back!");
            light.setState(OFF.getInstance());
        }
    }



    class Client {
        public static void main(String[] args) {
            Light light = new Light();
            light.on_button(); //Light On!;
            light.on_button(); //취침등 상태!;
            light.on_button(); //Light On Back!;
            light.off_button(); //Light off!;
            light.on_button(); //Light On!;
        }
    }

 

 

스테이트 패턴은 상태가 하나만 있어도 상관없기에 싱글톤을 사용한다.

State Pattern Strategy Pattern 많이 유사하다.

 

차이점은

 

상태패턴은 상태에 따라 다른일을 한다.

전략패턴 동일한 목표를 위해 다른 전략을 구사한다.

 

  • The Strategy pattern is really about having a different implementation that accomplishes (basically) the same thing, so that one implementation can replace the other as the strategy requires. For example, you might have different sorting algorithms in a strategy pattern. The callers to the object does not change based on which strategy is being employed, but regardless of strategy the goal is the same (sort the collection).
  • The State pattern is about doing different things based on the state, while leaving the caller relieved from the burden of accommodating every possible state. So for example you might have a getStatus() method that will return different statuses based on the state of the object, but the caller of the method doesn't have to be coded differently to account for each potential state.

상태패턴은 어떤 상태나 타입을 다룬다.  상태에 따른 행동을 캡슐화 한다.

전략패턴 어떻게 객체가 일을 할지를 다룬다. 알고리즘을 캡슐화 한다.


The State pattern deals with what (state or type) an object is (in) -- it encapsulates state-dependent behavior, whereasthe Strategy pattern deals with how an object performs a certain task -- it encapsulates an algorithm.


By using the State pattern the state-holding (context) class is relieved from knowledge of what state or type it is and what states or types that are available. This means that the class adheres to the open-closed design principle (OCP): the class is closed for changes in what states/types there are, but the states/types are open to extensions.

By using the Strategy pattern the algorithm-using (context) class is relieved from knowledge of how to perform a certain task (-- the "algorithm"). This case also creates an adherence to the OCP; the class is closed for changes regarding how to perform this task, but the design is very open to additions of other algorithms for solving this task.This likely also improves the context class' adherence to the single responsibility principle (SRP). Further the algorithm becomes easily available for reuse by other classes.

출처 

 

 

What is the difference between Strategy design pattern and State design pattern?

What are the differences between the Strategy design pattern and the State design pattern? I was going through quite a few articles on the web but could not make out the difference clearly. Can so...

stackoverflow.com

 

 

 

Comments