携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第二十八天,点击查看活动详情
重学设计模式之命令模式(Kotlin)
前言
命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。这样使得请求发送者与接受者消除彼此之间的耦合,让对象之间的调用关系更加灵活
命令模式可以对发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。这就是命令模式的模式动机
适用场景
-
系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互
-
在需要支持撤销和恢复撤销的地方,如GUI、文本编辑器等
-
需要用到日志请求、队列请求的地方
命令模式的角色以及职责
-
抽象命令类(Command): 定义命令的接口,声明执行的方法
-
具体命令(Concrete Command):具体的命令,实现命令接口;通常会持有接收者,并调用接收者的功能来完成命令要执行的操作。
-
实现者/接收者(Receiver) : 接收者,真正执行命令的对象。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能。
-
调用者/请求者(Invoker) : 要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口
实例
我们就以我们程序员的日常中,客户把开发订单给到老板,但是老板又不会开发,就命令我们根据订单来开发,呜呜呜,想想都为打工仔悲哀,出最大力那最少钱😭,我们就以这个悲惨的现象为例,实现命令模式:
- 创建抽象命令类
Command
interface Command{
//定义一个执行的行为
fun execute()
}
- 创建实现者/接收者 程序员
Programmer:
//程序员
class Programmer{
//添加功能
fun addRequirementCommand(){
System.out.println("需求增加了,加班赶需求!!!")
}
//删除功能
fun deleteRequirementCommand(){
System.out.println("需求不需要要求删除!!!什么!这不是逗我吗!!!!")
}
//修改功能
fun reviseRequirementCommand(){
System.out.println("需求要求修改!!!")
}
//划水
fun huashui(){
System.out.println("上掘金划划水!!!")
}
}
- 创建具体命令
- 增加需求命令:
class AddRequirementCommand(val xiaocai : Programmer) : Command {
override fun execute() {
xiaocai.addRequirementCommand()
}
}
- 修改需求命令
class ReviseRequirementCommand(val xiaocai : Programmer) : Command {
override fun execute() {
xiaocai.reviseRequirementCommand()
}
}
- 删除需求命令
class DeleteRequirementCommand(val xiaocai : Programmer) : Command {
override fun execute() {
xiaocai.deleteRequirementCommand()
}
}
- 创建调用者/请求者 老板
BossInvoker
class BossInvoker {
private var _command: Command? = null
//客户给boss提出需求
fun setCommand(command: Command) {
_command = command
}
//boss给programmer发出命令
fun action() {
_command?.execute()
}
}
- 模拟客户开始提出订单需求:
fun main() {
//客户找到boos
val boss = BossInvoker()
//boss找到小菜
val xiaocai= Programmer()
//用户需要增加需求,boss发出增加需求命令
boss.setCommand(AddRequirementCommand(xiaocai))
//执行命令
boss.action()
//用户需要修改需求,boss发出修改需求命令
boss.setCommand(ReviseRequirementCommand(xiaocai))
//执行命令
boss.action()
//用户需要删除需求,boss发出删除需求命令
boss.setCommand(DeleteRequirementCommand(xiaocai))
//执行命令
boss.action()
}
输出:
需求增加了,加班赶需求!!!
需求要求修改!!!
需求不需要要求删除!!!什么!这不是逗我吗!!!!
命令模式优缺点
优点:
-
降低系统的耦合度,命令模式能将调用操作的对象与实现该操作的对象解耦
-
满足“开闭原则”,对扩展比较灵活
-
可以实现宏命令。命令模式可以与组合模式结合,将多个命令装配成一个组合命令,即宏命令
-
方便实现 Undo 和 Redo 操作。命令模式可以与后面介绍的备忘录模式结合,实现命令的撤销与恢复
缺点:
-
使用命令模式可能会导致某些系统有过多的具体命令类
-
系统结构更加复杂