
Команда на Go
Команда — це поведінковий патерн, що дозволяє загортати запити або прості операції в окремі об’єкти.
Це дозволяє відкладати виконання команд, вибудовувати їх у чергу, а також зберігати історію і робити скасування.
Концептуальний приклад
Давайте розглянемо патерн Команда на прикладі телевізора. ТV може бути увімкнено двома способами:
- кнопка УВІМК на пульті дистанційного керування;
- кнопка ВИМК на самому телевізорі.
Ми можемо почати з реалізації об’єкта команди УВІМК з телевізором у ролі одержувача. Коли на цю команду викликається метод execute
, вона, у свою чергу, викликає функцію 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