겨울 세일!
커맨드

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로 작성된 커맨드 파이썬으로 작성된 커맨드 루비로 작성된 커맨드 러스트로 작성된 커맨드 스위프트로 작성된 커맨드 타입스크립트로 작성된 커맨드