![커맨드](/images/patterns/cards/command-mini.png?id=b149eda017c0583c1e92343b83cfb1eb)
Go로 작성된 커맨드
커맨드는 요청 또는 간단한 작업을 객체로 변환하는 행동 디자인 패턴입니다.
이러한 변환은 명령의 지연 또는 원격 실행, 명령 기록 저장 등을 허용합니다.
개념적인 예시
TV를 예시로 든 커맨드 패턴을 살펴봅시다. 다음 중 하나를 통해 TV를 켤 수 있습니다:
- 리모컨의 ON버튼
- 실제 TV의 ON 버튼.
일단 TV를 수신기로 사용하여 ON 커맨드 객체를 구현할 수 있습니다. 이 커맨드에 실행 메서드가 호출되면 해당 커맨드는 TV.on
함수를 호출합니다. 마지막으로 호출자를 정의해야 합니다. 우리는 실제로 두 호출자가 있을 것입니다: 리모컨과 실제 TV. 두 커맨드 다 ON 커맨드 객체를 포함할 것입니다.
같은 요청을 여러 호출자로 래핑한 점을 주목해 주세요. 다른 커맨드들을 같은 방법으로 래핑할 수 있습니다. 별도의 커맨드 객체를 만드는 이점은 기본 비즈니스 논리에서 사용자 인터페이스 논리를 분리한다는 점이며 또 각 호출자에 대해 다른 핸들러를 개발할 필요가 없습니다. 커맨드 객체에는 실행에 필요한 모든 정보가 포함되어 있습니다. 따라서 해당 객체는 지연된 실행에도 사용될 수 있습니다.
button.go: 호출자
package main
type Button struct {
command Command
}
func (b *Button) press() {
b.command.execute()
}
command.go: 커맨드 인터페이스
package main
type Command interface {
execute()
}
onCommand.go: 구상 커맨드
package main
type OnCommand struct {
device Device
}
func (c *OnCommand) execute() {
c.device.on()
}
offCommand.go: 구상 커맨드
package main
type OffCommand struct {
device Device
}
func (c *OffCommand) execute() {
c.device.off()
}
device.go: 수신자 인터페이스
package main
type Device interface {
on()
off()
}
tv.go: 구상 수신자
package main
import "fmt"
type Tv struct {
isRunning bool
}
func (t *Tv) on() {
t.isRunning = true
fmt.Println("Turning tv on")
}
func (t *Tv) off() {
t.isRunning = false
fmt.Println("Turning tv off")
}
main.go: 클라이언트 코드
package main
func main() {
tv := &Tv{}
onCommand := &OnCommand{
device: tv,
}
offCommand := &OffCommand{
device: tv,
}
onButton := &Button{
command: onCommand,
}
onButton.press()
offButton := &Button{
command: offCommand,
}
offButton.press()
}
output.txt: 실행 결과
Turning tv on
Turning tv off