当前位置: 代码迷 >> 综合 >> 设计模式之 命令模式实例笔记
  详细解决方案

设计模式之 命令模式实例笔记

热度:66   发布时间:2024-02-23 20:33:59.0

模拟一个电器遥控器,里面可以控制电灯/电视/空调等电器的 开 和 关 , 并且提供 撤销按钮。

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 不需要做修改。

命令与最终实现者解耦

  相关解决方案