Command模式属于行为模式,做为大名鼎鼎的23个设计模式之一,Command模式理解起来不如工厂模式,单例模式等那么简单直白。究其缘由,行为模式着重于使用,若是没有编程实践,确实不如创造模式那么直白。咱们先看看UML类图。编程
估计不少同窗看着图就晕了,那么多东西,Command和Concrete Command还好理解,那些Receiver和Invoker又是什么东西呢?
别着急,只要理解了一点,这个模式就很容易理解了,下面划重点,Command模式最主要的特色,是将命令封装成类,在类中保存命令执行的上下文(即该命令执行的参数,执行的对象),以实现命令执行对象和命令发出对象的解耦。
这样一来是否是以为好理解多了?Command类里面的Receiver,就是命令具体执行的对象。这里的Client能够理解为装配环境,在这里面代码实例化Command。Invoker内部保存命令(能够保存多条命令,实现命令记录查看,撤销等),客户端代码经过Invoker来操做命令。接下来咱们看看示例代码。设计模式
首先咱们定义一个支持撤销的Command接口。设计
interface Command { void Execute(); void Undo(); }
接下来咱们定义Receiver,也就是命令的执行对象,这里咱们定义一个Ball类。code
class Ball { public int Size { get; set; } = 10; public string Name { get; set; } = "My First Ball"; public void Inspect() { Console.WriteLine("My Name is {0} and size is {1}", Name, Size); } }
这里定义两个命令,一个修更名字,一个修改大小。对象
class ChangeNameCommand : Command { private Ball _Ball; private string _OldName; public string NameYouWant { get; set; } public ChangeNameCommand(Ball ball) { _Ball = ball; } public void Execute() { _OldName = _Ball.Name; _Ball.Name = NameYouWant; } public void Undo() { _Ball.Name = _OldName; } } class ChangeSizeCommand : Command { //代码大同小异,略 }
接下来是Invoker,,也就是存储命令,并最终会被用户代码调用的类,这里咱们叫它CommandManager。blog
class CommandManager { private Stack<Command> commands = new Stack<Command>(); public void RunCommand(Command command) { command.Execute(); commands.Push(command); } public void Undo() { if (commands.Count > 0) { var command = commands.Pop(); command.Undo(); } } public void ShowCommands() { var temp = commands.Reverse(); foreach(var command in temp) { //display command } } }
如今咱们看看客户端代码是怎么使用他们的,定义Ball,定义命令,经过CommandManager去调用,这样能够方便查看命令记录,撤销命令,等。接口
static void Main(string[] args) { Ball ball = new Ball(); ball.Inspect(); ChangeNameCommand changeName = new ChangeNameCommand(ball) { NameYouWant = "Changed" }; ChangeSizeCommand changeSize = new ChangeSizeCommand(ball) { SizeYouWant = 20 }; CommandManager manager = new CommandManager(); manager.RunCommand(changeName); manager.RunCommand(changeSize); ball.Inspect(); manager.ShowCommands(); manager.Undo(); ball.Inspect(); manager.Undo(); ball.Inspect(); }
就酱,咱们已经实现了命令模式,而且还支持命令的记录与撤销,但愿能对你们有点帮助。get