State Pattern

상태 패턴 특징

단일 책임 원칙 : 특정 상태와 관련된 코드를 별도의 클래스로 구성
개방 폐쇄 원칙
부피가 큰 조건문을 제거하여 컨텍스트의 코드 단순화
전략패턴, 브릿지 패턴, (일부 어댑터패턴) 과 유사한 구조를 가짐.
단점
상태 시스템에 몇 가지 상태만 있거나 거의 변경되지 않는 경우 패턴을 적용하는 것이 과도할 수 있음.

상태 패턴 의 클래스 다이어그램

예제 - 노트북 전원

노트북의 전원을 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
복사

Reference