봄맞이 세일
커맨드

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

다른 언어로 작성된 커맨드

C#으로 작성된 커맨드 C++로 작성된 커맨드 자바로 작성된 커맨드 PHP로 작성된 커맨드 파이썬으로 작성된 커맨드 루비로 작성된 커맨드 러스트로 작성된 커맨드 스위프트로 작성된 커맨드 타입스크립트로 작성된 커맨드