模拟一个电器遥控器,里面可以控制电灯/电视/空调等电器的 开 和 关 , 并且提供 撤销按钮。
1. 命令抽象接口
interface Command {
fun execute()
fun undo()
}
2. 接收者(最终实现者)
import android.util.Log
class LightReceiver {
fun on() {
Log.d("LightReceiver", "电灯打开了.......")
}
fun off() {
Log.d("LightReceiver", "电灯关闭了.......")
}
}
3. 命令具体实现者
class LightOnCommand : Command{
private var receiver: LightReceiver
constructor(receiver: LightReceiver) {
this.receiver = receiver
}
override fun execute() {
receiver.on()
}
override fun undo() {
receiver.off()
}
}
class LightOffCommand : Command {
private var receiver: LightReceiver
constructor(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: Command
private var DEVICES_SIZE = 5
constructor() {
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] = onCommand
offCommands[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. 客户端调用 (模拟)
@Test
fun 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.Log
class TVReceiver {
fun on() {
Log.d("TVReceiver", "电视打开了.......")
}
fun off() {
Log.d("TVReceiver", "电视关闭了.......")
}
}
class TVOnCommand : Command{
private var receiver: TVReceiver
constructor(receiver: TVReceiver) {
this.receiver = receiver
}
override fun execute() {
receiver.on()
}
override fun undo() {
receiver.off()
}
}
class TVOffCommand : Command{
private var receiver: TVReceiver
constructor(receiver: TVReceiver) {
this.receiver = receiver
}
override fun execute() {
receiver.off()
}
override fun undo() {
receiver.on()
}
}
8. 客户端调用
@Test
fun 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 不需要做修改。
命令与最终实现者解耦