命令模式

命令模式(Command Pattern):将一个请求封装为一个对象,以便使用不同的对象。命令模式解决了应用程序中对象的职责,以及他们之间的通信方式。

适用场景

  • 请求调用者和请求接收者需要解耦,使得调用者和接收者不直接交互

  • 需要抽象出等待执行的行为

优点

  • 降低解耦

  • 容易扩展新命令或者一组新命令

缺点

  • 命令的无限扩展会增加类的数量,提高系统的实现复杂度

下面我们引入一种应用场景。在万物互联智能化的今天,大部分的家居产品都可以使用app来进行控制了。就以家里的智能灯为例。我们可以通过一个app控制家里的多个灯。或者对一个灯,进行反复的开关操作。

Golang Demo

package command

import (
    "fmt"
)

type Command interface {
    execute()
}

type Light struct {
    name string
}

func NewLight(name string) *Light {
    return &Light{name: name}
}

func (l *Light) open() {
    fmt.Println("open light " + l.name)
}
func (l *Light) close() {
    fmt.Println("close light " + l.name)
}

type OpenLightCommand struct {
    light *Light
}

func (o *OpenLightCommand) execute() {
    o.light.open()
}

func NewOpenLightCommand(light *Light) *OpenLightCommand {
    return &OpenLightCommand{light: light}
}

type CloseLightCommand struct {
    light *Light
}

func (c *CloseLightCommand) execute() {
    c.light.close()
}

func NewCloseLightCommand(light *Light) *CloseLightCommand {
    return &CloseLightCommand{light: light}
}

type App struct {
    commandList []Command
}

func NewApp() *App {
    return &App{}
}

func (a *App) addCommand(command Command) {
    a.commandList = append(a.commandList, command)
}

func (a *App) executeCommand() {
    for _, command := range a.commandList {
        command.execute()
    }
    // 清空这个切片
    a.commandList = a.commandList[0:0]
}

Java Demo

首先我们定义一个命令接口。

创建一款智能灯。

设计相应的开灯命令,和关灯命令。

接下来,我们定义一个app类型的模拟类,这里面可以批量的接收和执行command

UML

命令模式UML

补充另一个版本的Java/Scala Demo 以及源码解析

Java Demo_

Scala Demo

UML_

源码解析

Last updated