상태 패턴 특징
•
단일 책임 원칙 : 특정 상태와 관련된 코드를 별도의 클래스로 구성
•
개방 폐쇄 원칙 
•
부피가 큰 조건문을 제거하여 컨텍스트의 코드 단순화
•
전략패턴, 브릿지 패턴, (일부 어댑터패턴) 과 유사한 구조를 가짐.
단점
•
상태 시스템에 몇 가지 상태만 있거나 거의 변경되지 않는 경우 패턴을 적용하는 것이 과도할 수 있음.
상태 패턴 의 클래스 다이어그램
예제 - 노트북 전원
•
노트북의 전원을 ON/OFF/절전모드 할 수 있는 버튼이 있다.
•
각 버튼에 state pattern을 적용한다.
PowerState
// js
export interface PowerState {
  powerPush: () => string;
}
JavaScript
복사
// java
public interface PowerState {
    public void powerPush();
}
Java
복사
PowerOn
// js
import { PowerState } from './PowerState';
export class PowerOn implements PowerState {
  powerPush = () => {
    return '전원 On';
  };
}
JavaScript
복사
// java
public class PowerOn implements PowerState{
    public void powerPush(){
        System.out.println("전원 On");
    }
}
Java
복사
PowerOff
// js
import { PowerState } from './PowerState';
export class PowerOff implements PowerState {
  powerPush = () => {
    return '전원 Off';
  };
}
Java
복사
// java
public class PowerOff implements PowerState {
    public void powerPush(){
        System.out.println("절전 Off");
    }
}
Java
복사
PowerSave
// js
import { PowerState } from './PowerState';
export class PowerSave implements PowerState {
  powerPush = () => {
    return '절전모드';
  };
}
Java
복사
// java
public class PowerSave implements PowerState {
    public void powerPush(){
        System.out.println("절전모드");
    }
}
Java
복사
Laptop
•
Laptop 클래스 추가
•
분기코드를 제거
•
인터페이스의 powerPush() 메서드를 호출
// js 변경 후
import { PowerOff } from './PowerOFF';
import { PowerState } from './PowerState';
export class Laptop {
  private powerState: PowerState;
  constructor() {
    this.powerState = new PowerOff();
  }
  setPowerState(powerState: PowerState) {
    this.powerState = powerState;
  }
  powerPush(): string {
    return this.powerState.powerPush();
  }
}
JavaScript
복사
// js 이전 코드
export class Laptop {
  powerOn = 'on';
  powerOff = 'off';
  powerSave = 'saving';
  powerState = '';
  constructor() {
    this.powerState = this.powerOff;
  }
  setPowerState(powerState: string) {
    this.powerState = powerState;
  }
  powerPush(): string {
    if (this.powerState === 'on') {
      return '전원 On';
    } else if (this.powerState === 'off') {
      return '전원 Off';
    } else {
      //if(this.powerState === 'saving')
      return '절전모드';
    }
  }
}
JavaScript
복사
// java 변경 후
public class Laptop {
    private PowerState powerState;
    public Laptop(){
        this.powerState = new PowerOff();
    }
    public void setPowerState(PowerState powerState){
        this.powerState = powerState;
    }
    public void powerPush(){
        powerState.powerPush();
    }
	}
}
Java
복사
// java 이전 코드
public class Laptop {
    public static String PowerOn = "on";
    public static String PowerOff = "off";
    public static String PowerSave = "saving";
    private String powerState = "";
    public Laptop(){
        setPowerState(Laptop.OFF);
    }
    public void setPowerState(String powerState){
        this.powerState = powerState;
    }
    public void powerPush(){
        if ("on".equals(this.powerState)) {
            System.out.println("전원 On");
        }
        else if ("saving".equals(this.powerState)){
            System.out.println("절전 모드");
        }
        else {
            System.out.println("전원 Off");
        }
    }
}
Java
복사
View(= Main)
// js
import { Laptop } from './ts/Laptop';
import { PowerOff } from './ts/PowerOFF';
import { PowerOn } from './ts/PowerOn';
import { PowerSave } from './ts/PowerSave';
const laptop = new Laptop();
const powerOn = new PowerOn();
const powerOff = new PowerOff();
const PowerSaving = new PowerSave();
const $saveOn = <HTMLButtonElement>document.querySelector('#saveOn');
const $saveOff = <HTMLButtonElement>document.querySelector('#saveOff');
const $saving = <HTMLButtonElement>document.querySelector('#saving');
const $laptopState = <HTMLButtonElement>document.querySelector('#current_laptop');
$laptopState.innerHTML = laptop.powerPush();
$saveOn.onclick = () => {
  laptop.setPowerState(powerOn);
  $laptopState.innerHTML = laptop.powerPush();
};
$saveOff.onclick = () => {
  laptop.setPowerState(powerOff);
  $laptopState.innerHTML = laptop.powerPush();
};
$saving.onclick = () => {
  laptop.setPowerState(PowerSaving);
  $laptopState.innerHTML = laptop.powerPush();
};
Java
복사
// java
public class Client {
    public static void main(String args[]){
        Laptop laptop = new Laptop();
        PowerOn on = new PowerOn();
        PowerOff off = new PowerOff();
        PowerSave saving = new PowerSave();
        laptop.powerPush();
        laptop.setPowerState(on);
        laptop.powerPush();
        laptop.setPowerState(saving);
        laptop.powerPush();
        laptop.setPowerState(off);
        laptop.powerPush();
        laptop.setPowerState(on);
        laptop.powerPush();
    }
}
Java
복사

