模拟一个电器遥控器,里面可以控制电灯/电视/空调等电器的 开 和 关 , 并且提供 撤销按钮。
1. 命令抽象接口
interface Command {fun execute()fun undo()
}
2. 接收者(最终实现者)
import android.util.Logclass LightReceiver {fun on() {Log.d("LightReceiver", "电灯打开了.......")}fun off() {Log.d("LightReceiver", "电灯关闭了.......")}
}
3. 命令具体实现者
class LightOnCommand : Command{private var receiver: LightReceiverconstructor(receiver: LightReceiver) {this.receiver = receiver}override fun execute() {receiver.on()}override fun undo() {receiver.off()}
}
class LightOffCommand : Command {private var receiver: LightReceiverconstructor(receiver: LightReceiver) {this.receiver = receiver}override fun execute() {receiver.off()}override fun undo() {receiver.on()}
}
4. 控制器 (遥控器)
class RemoteController {private var onCommands = mutableListOf<Command>()private var offCommands = mutableListOf<Command>()private lateinit var undoCommand: Commandprivate var DEVICES_SIZE = 5constructor() {initCommands()}private fun initCommands() {for (i in 0 until DEVICES_SIZE) {onCommands.add(EmptyCommand())offCommands.add(EmptyCommand())}}fun setCommand(which: Int, onCommand: Command, offCommand: Command) {onCommands[which] = onCommandoffCommands[which] = offCommand}fun onButtonWasPressed(which: Int) {onCommands[which].execute()undoCommand = onCommands[which]}fun offButtonWasPressed(which: Int) {offCommands[which].execute()undoCommand = offCommands[which]}fun undoButtonWasPressed(){undoCommand.undo()}
}
5. 客户端调用 (模拟)
@Testfun testCommand(){var remoteController = RemoteController()var lightReceiver = LightReceiver()var lightOffCommand = LightOffCommand(lightReceiver)var lightOnCommand = LightOnCommand(lightReceiver)remoteController.setCommand(0, lightOnCommand, lightOffCommand)Log.d(TAG, "====================按下电灯开的按钮====================")remoteController.onButtonWasPressed(0)Log.d(TAG, "====================按下电灯关的按钮====================")remoteController.offButtonWasPressed(0)Log.d(TAG, "====================撤销上一次的操作====================")remoteController.undoButtonWasPressed()}
6. 输出结果
09-29 10:45:55.020 D 16957 16990 DesignPattern: ====================按下电灯开的按钮====================
09-29 10:45:55.020 D 16957 16990 LightReceiver: 电灯打开了.......
09-29 10:45:55.021 D 16957 16990 DesignPattern: ====================按下电灯关的按钮====================
09-29 10:45:55.021 D 16957 16990 LightReceiver: 电灯关闭了.......
09-29 10:45:55.021 D 16957 16990 DesignPattern: ====================撤销上一次的操作====================
09-29 10:45:55.021 D 16957 16990 LightReceiver: 电灯打开了.......
7. 增加一个电视 (只需增加 接受者/ 开和关的实现者)
import android.util.Logclass TVReceiver {fun on() {Log.d("TVReceiver", "电视打开了.......")}fun off() {Log.d("TVReceiver", "电视关闭了.......")}
}
class TVOnCommand : Command{private var receiver: TVReceiverconstructor(receiver: TVReceiver) {this.receiver = receiver}override fun execute() {receiver.on()}override fun undo() {receiver.off()}
}
class TVOffCommand : Command{private var receiver: TVReceiverconstructor(receiver: TVReceiver) {this.receiver = receiver}override fun execute() {receiver.off()}override fun undo() {receiver.on()}
}
8. 客户端调用
@Testfun testCommand(){var remoteController = RemoteController()var lightReceiver = LightReceiver()var lightOffCommand = LightOffCommand(lightReceiver)var lightOnCommand = LightOnCommand(lightReceiver)remoteController.setCommand(0, lightOnCommand, lightOffCommand)Log.d(TAG, "====================按下电灯开的按钮====================")remoteController.onButtonWasPressed(0)Log.d(TAG, "====================按下电灯关的按钮====================")remoteController.offButtonWasPressed(0)Log.d(TAG, "====================撤销上一次的操作====================")remoteController.undoButtonWasPressed()Log.d(TAG, "====================----------====================")var tvReceiver = TVReceiver()var tvOffCommand = TVOffCommand(tvReceiver)var tvOnCommand = TVOnCommand(tvReceiver)remoteController.setCommand(1, tvOnCommand, tvOffCommand)Log.d(TAG, "====================按下电视开的按钮====================")remoteController.onButtonWasPressed(0)Log.d(TAG, "====================按下电视关的按钮====================")remoteController.offButtonWasPressed(0)Log.d(TAG, "====================撤销上一次的操作====================")remoteController.undoButtonWasPressed()}
9. 完整输出
09-29 10:45:55.020 D 16957 16990 DesignPattern: ====================按下电灯开的按钮====================
09-29 10:45:55.020 D 16957 16990 LightReceiver: 电灯打开了.......
09-29 10:45:55.021 D 16957 16990 DesignPattern: ====================按下电灯关的按钮====================
09-29 10:45:55.021 D 16957 16990 LightReceiver: 电灯关闭了.......
09-29 10:45:55.021 D 16957 16990 DesignPattern: ====================撤销上一次的操作====================
09-29 10:45:55.021 D 16957 16990 LightReceiver: 电灯打开了.......
09-29 10:45:55.021 D 16957 16990 DesignPattern: ====================----------====================
09-29 10:45:55.021 D 16957 16990 DesignPattern: ====================按下电视开的按钮====================
09-29 10:45:55.021 D 16957 16990 LightReceiver: 电灯打开了.......
09-29 10:45:55.021 D 16957 16990 DesignPattern: ====================按下电视关的按钮====================
09-29 10:45:55.021 D 16957 16990 LightReceiver: 电灯关闭了.......
09-29 10:45:55.021 D 16957 16990 DesignPattern: ====================撤销上一次的操作====================
09-29 10:45:55.021 D 16957 16990 LightReceiver: 电灯打开了.......
可见,新增的时候, RemoteController 不需要做修改。
命令与最终实现者解耦