프런트엔드/디자인 패턴

[2일차] 명령 | 행동 패턴 11일만에 끝내기 챌린지 - GoF 디자인 패턴

조드래곤나인 2023. 7. 16. 15:01

 

출처: 에릭 감마 , 리처드 헬름 , 랄프 존슨 , 존 블리시디스. 『Gof의 디자인 패턴』. 김정아(역). 프로텍미디어, 2015.

 

 

[2일차] 명령(Command)
행동 패턴 11일만에 끝내기 챌린지 - GoF 디자인 패턴

타입스크립트로 설명하는 GoF 디자인 패턴의 행동 패턴 11일만에 끝내기 챌린지

 

 

명령이란?

명령 패턴은 요청 자체를 캡슐화하는 것입니다.
이를 통해 요청이 서로 다른 사용자를 매개변수로 만들고,
요청을 대기 시키거나 로깅하여, 되돌릴 수 있는 연산을 지원합니다.

 

 

활용성

1) 수행할 동작을 객체로 매개변수화하고자 할 때
절차지향 프로그래밍에서는 이를 콜백 함수,
즉 어딘가 등록되었다가 나중에 호출되는 함수를 사용해서 이러한 매개변수화를 표현할 수 있다.
명령 패턴은 콜백을 객체지향 방식으로 나타낸 것이다.

2) 서로 다른 시간에 요청을 명시하고, 저장하며, 실행하고 싶을 때.

3) 실행 취소 기능을 지원하고 싶을 때.

Command의 execute() 연산은 상태를 저장할 수 있는 데,

이를 이용해서 지금까지 얻은 결과를 바꿀 수 있다.

이를 위해 unexecute() 연산을 Command 클래스의 인터페이스에 추가한다.

 

4) 시스템이 고장 났을 때 재적용이 가능하도록 변경 과정에 대한 로깅을 지원하고 싶을 때.

Command 인터페이스를 확장해서 load()와 store()연산을 정의하면

상태의 변화를 지속적(persistant) 저장소에 저장해 둘 수 있다.

 

5) 기본적인 연산의 조합으로 만든 상위 수준 연산을 써서 시스템을 구조화하고 싶을 때.

일련의 과정을 통해 데이터를 변경하는 트랜젝션(transaction)의 모델링을 가능하게 한다.

 

 

구조 및 구현

interface Command {
    execute(): void
}

class ConcreteCommand implements Command {
    private receiver: Receiver
    constructor(receiver: Receiver) {
        this.receiver = receiver
    }
    execute(): void {
        console.log('ConcreteCommand Execute')
        this.receiver.action()
    }
}

class Receiver {
    action() {
        console.log('Receiver Action')
    }
}

class Invoker {
    private commands: Command[] = []

    storeCommand(command: Command) {
        this.commands.push(command)
        command.execute()
    }
}
 
class Main {
    constructor() {
        const receiver = new Receiver()
        const command = new ConcreteCommand(receiver)
        const invoker = new Invoker()

        invoker.storeCommand(command)
        // ConcreteCommand Execute
        // Receiver Action
    }
}
 

 


 

728x90