比如,奶奶今天想吃饺子,将命令发布给爸爸,爸爸就得去做饺子
奶奶属于请求者角色,发布做饺子命令为具体命令,爸爸充当接收者角色
其实命令模式就是请求者将要做的事情告诉接收者,中间需要经过一个抽象命令接口,然后具体实现
如图:
例子:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 命令模式
{
//请求者角色,命令发布者
public sealed class Invoker
{
private Command command;
public Invoker(Command command)
{
this.command = command;
}
public void ExcecuteCommand()
{
command.MakeDumplings();
}
}
//抽象命令角色,任务是包饺子
public abstract class Command
{
protected Receiver worker;
protected Command(Receiver receiver)
{
worker = receiver;
}
public abstract void MakeDumplings();
}
//具体命令角色,干哪些事
public sealed class MakeDumplingCommand : Command
{
public MakeDumplingCommand(Receiver receiver) : base(receiver) { }
public override void MakeDumplings()
{
worker.Excute("今天猪肉韭菜的饺子");
}
}
//具体命令接受角色,是谁要干这些事
public sealed class Receiver
{
public void Excute(string job)
{
Console.WriteLine(job);
}
}
class Client
{
static void Main(string[] args)
{
Receiver receiver = new Receiver();
Command command = new MakeDumplingCommand(receiver);
Invoker invoker = new Invoker(command);
invoker.ExcecuteCommand();
Console.ReadKey();
}
}
}
四、命令模式的适用场景
在下面的情况下可以考虑使用命令模式:
1.系统需要支持命令的撤销(undo)。命令对象可以把状态存储起来,等到客户端需要撤销命令所产生的效果时,可以调用undo方法吧命令所产生的效果撤销掉。命令对象还可以提供redo方法,以供客户端在需要时,再重新实现命令效果。
2.系统需要在不同的时间指定请求、将请求排队。一个命令对象和原先的请求发出者可以有不同的生命周期。意思为:原来请求的发出者可能已经不存在了,而命令对象本身可能仍是活动的。这时命令的接受者可以在本地,也可以在网络的另一个地址。命令对象可以串行地传送到接受者上去。
3.如果一个系统要将系统中所有的数据消息更新到日志里,以便在系统崩溃时,可以根据日志里读回所有数据的更新命令,重新调用方法来一条一条地执行这些命令,从而恢复系统在崩溃前所做的数据更新。
4.系统需要使用命令模式作为“CallBack(回调)”在面向对象系统中的替代。Callback即是先将一个方法注册上,然后再以后调用该方法。
五、命令模式的优缺点
命令模式使得命令发出的一个和接收的一方实现低耦合,从而有以下的优点:
1.命令模式使得新的命令很容易被加入到系统里。
2.可以设计一个命令队列来实现对请求的Undo和Redo操作。
3.可以较容易地将命令写入日志。
4.可以把命令对象聚合在一起,合成为合成命令。合成命令式合成模式的应用。
命令模式的缺点:
使用命令模式可能会导致系统有过多的具体命令类。这会使得命令模式在这样的系统里变得不实际。
总结:命令模式并通过加入命令请求者角色来实现将命令发送者对命令执行者的依赖分割开达到松耦合,如果直接发送就是强耦合