设计模式总结之命令模式(Command Pattern)

  • A+
所属分类:设计模式

首先,我们需要思考一下为什么要用命令模式命令模式可以让调用者和执行者之间解耦,调用者无需知道是如何执行的,只用告诉执行者可以执行了,执行者完成执行就行了。

那么如何做到这一点呢?假设我们有一个遥控器,有多个插槽,每个插槽可以控制多个东西的开关,比如电灯,房门,电视等等。以往我们的做法是,新建一个电灯遥控器类RemoteControl,当遥控器按下时,写if else判断是电灯还是房门还是电视,然后调用相关的on或off方法即可。是不是觉得这样完全没有违和感?但这样有一个问题是,所有代码都需要写在RemoteControl里,这样就会有一堆if else的判断,如果又有新的东西需要加进遥控器里,就必须要修改这个类的代码。

而命令模式的做法是,首先新建一个Command接口,接口里只有execute方法。

现在电灯有开(on)和关(off)两个方法,也就是两个命令,我们把这两个命令单独拿出来成为两个类LightOnCommand,LightOffCommand,实现Command接口。然后execute方法里调用电灯类Light的开关方法。在遥控器类RemoteControl里只和Command打交道,具体来说就是在RemoteControl里持有Command对象,我们有一个SetCommand方法可以设定Command。也就让遥控器和电灯解耦了。这样如果我们需要将房门开关的功能加到遥控器里时,我们不需要修改之前的代码,只用再新建房门开关的两个类DoorOpenCommand,DoorCloseCommand即可。这样就遵守了开放(易于扩展)封闭(不修改原来的代码)原则。

命令模式的好处还不止这些,它可以让你动态的改变Command,比如现在遥控器的第一个插槽里放的是电灯的开关,在不修改代码的前提下,我可以很轻易的通过setCommand方法来改变它为房门的开关。

另外,命令模式还支持撤消动作。这个在实际中也有很多应用,比如服务器通过日志恢复宕机前的所有操作,听起来很神奇,其实也很简单,就是在执行命令时在日志里记录下执行的命令即可。你们可能会说,这个例子和撤消有什么关系?撤消,说白了,也是要记录上一次执行的命令,点击撤消时,把记录好的命令执行一次就行了。所以本质上是一样的。

ZPY

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: