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

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

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

命令与最终实现者解耦

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值