Design Pattern

State pattern, 스테이트 패턴

iKay 2020. 4. 28. 00:14
반응형

State pattern 이란

객체가 상태에 따라 같은 메소드가 다른 행위를 하도록 위임하는 디자인 패턴이다. 공통 메소드의 인터페이스를 통해, 각 상태는 클래스로 분리시켜 표현한다.

 

 

State pattern 적용

 

아래 예는 스타크래프트의 시즈탱크의 시즈모드 활성화, 비활성화를 State 패턴을 적용해본 것이다.

 

시즈탱크의 시즈모드는 멱등성을 가진다. 즉, 시즈탱크는 시즈모드가 활성화 됐을 때 시즈모드를 할 수 없고 시즈모드 비활성화만 할 수 있다. 반대로 비활성화 된 경우 시즈모드 활성화를 할 수 있지만 비활성화는 할 수 없다. 이런 구현을 state 패턴으로 할 수 있다. 또한 같은 공격(attack) 메소드라 할지라도  시즈모드 활성화, 비활성화 상태에 따라 공격하는 방식이 다른데 이런 구현도 가능하다.

 

 

interface State {
    enableSizeMode(sizeTank: SizeTank): void;
    disableSizeMode(sizeTank: SizeTank): void;
    attack(): void;
}

class OnSizeMode implements State {
    enableSizeMode(sizeTank: SizeTank): void {
        console.log('시즈모드를 활성화 할 수 없다.');
    }
    disableSizeMode(sizeTank: SizeTank): void {
        console.log('시즈모드 비활성화!');
        sizeTank.setState(new OffSizeMode());
    }
    attack(): void {
        console.log('대포 발사');
    }
}

class OffSizeMode implements State {
    enableSizeMode(sizeTank: SizeTank): void {
        console.log('시즈모드 활성화!');
        sizeTank.setState(new OnSizeMode());
    }
    disableSizeMode(sizeTank: SizeTank): void {
        console.log('시즈모드 비활성를 할 수 없다');
    }
    attack(): void {
        console.log('퉁퉁포 발사');
    }
}

class SizeTank {
    constructor(private state: State = new OffSizeMode()) {}

    setState(state: State) {
        this.state = state;
    }

    activeSizeMode() {
        this.state.enableSizeMode(this);
    }

    inActiveSizeMode() {
        this.state.disableSizeMode(this);
    }

    attack() {
        this.state.attack();
    }
}

function Main() {
    const sizeTank = new SizeTank();
    sizeTank.attack(); // 퉁퉁포 발사

    sizeTank.activeSizeMode(); // 시즈모드 활성화!
    sizeTank.activeSizeMode(); // 시즈모드를 활성화 할 수 없다.

    sizeTank.attack(); // 대포 발사
    sizeTank.attack(); // 대포 발사

    sizeTank.inActiveSizeMode(); // 시즈모드 비활성화!
    sizeTank.inActiveSizeMode(); // 시즈모드 비활성를 할 수 없다
}

Main();

 

결론

 

비즈니스 로직을 구현할 때 상태를 갖는 객체는 상태에 따라 같은 메소드라 할지라도 다르게 동작해야 할 경우가 있다. 예를 들어, 쇼핑몰에서 "주문 배송지 변경" 이라는 비즈니스 로직은 주문의 상태가 "배송 전' 일 때 가능하지 "배송 후"에는 불가능해야 한다. 이와 비슷한 경우 State pattern 패턴을 적용하면 될 것 같다.

반응형

'Design Pattern' 카테고리의 다른 글

Observer pattern, 옵저버 패턴  (0) 2020.05.18
Command Pattern, 커맨트 패턴  (0) 2020.04.13
Singleton pattern, 싱글톤 패턴  (0) 2020.04.02
Strategy pattern, 스트레이티지 패턴  (0) 2020.04.01