1. 简介
命名模式将请求封装成一个对象:
- 从发出者发出命令,发出者不用关心谁接收命令,只要把命令发出即可
- 从接收者接收命令,接收者不用关心谁发出命令,只要把每次命令接收
接收者也可以看成命令执行者
1.1 作用
- 命令模式解耦了命名发出者和接收者
优缺点
✔ 优点 | ❌ 缺点 |
---|---|
单一职责原则:可以解耦触发和执行操作的类 | 代码可能会变得更加复杂, 因为你在发送者和接收者之间增加了一个全新的层次 |
开闭原则:可以在不修改已有客户端代码的情况下在程序中创建新的命令 | |
可以实现撤销和恢复功能 | |
可以实现操作的延迟执行 | |
可以将一组简单命令组合成一个复杂命令 |
1.2使用场景
- 实现操作回滚功能,可以使用命令模式
- 通过参数来参数化对象,可以用命令模式
- 将操作放入队列、操作的执行或远程执行操作,可以用命令模式
现实场景
- 顾客是
Client
- 厨师是
Receiver
- 订单是命令
2. 实现
2.1 UML 图
- 把命令封装在一个类中:
Command
基类 - 把接收对象封装在一个类中:
Receiver
- 由
Invoker
来调用命令(类似注册回调函数的原理)
2.2 代码
Program:
namespace Command
{
class Program
{
static void Main(string[] args)
{
Invoker invoker = new Invoker();
SimpleCommand simple = new SimpleCommand("sscc");
invoker.SetCommand(simple);
invoker.ExecuteCommand();
Receiver receiver = new Receiver();
ComplexCommand complex = new ComplexCommand(receiver, "dd", "ee");
invoker.SetCommand(complex);
invoker.ExecuteCommand();
}
}
}
Invoker:
namespace Command
{
class Invoker
{
public Command command;
public void SetCommand(Command command)
{
this.command = command;
}
public void ExecuteCommand()
{
command.Execute();
}
}
}
Receiver:
using System;
namespace Command
{
class Receiver
{
public void DoSomething(string str)
{
Console.WriteLine("Receiver DoSomething on " + str);
}
public void DoSomethingElse(string str)
{
Console.WriteLine("Receiver DoSomethingElse on " + str);
}
}
}
Command:
namespace Command
{
interface Command
{
public void Execute() { }
}
}
SimpleCommand:
using System;
namespace Command
{
class SimpleCommand: Command
{
private string simplestr = "";
public SimpleCommand(string str)
{
simplestr = str;
}
public void Execute()
{
Console.WriteLine("SimpleCommand Execute " + simplestr);
}
}
}
ComplexCommand:
using System;
namespace Command
{
class ComplexCommand: Command
{
private Receiver receiver;
private string doSomethingStr = "";
private string doSomethingElseStr = "";
public ComplexCommand(Receiver r,string doSomething,string doSomethingElse)
{
receiver = r;
doSomethingStr = doSomething;
doSomethingElseStr = doSomethingElse;
}
public void Execute()
{
receiver.DoSomething(doSomethingStr);
receiver.DoSomethingElse(doSomethingElseStr);
}
}
}
F5 运行结果:
SimpleCommand Execute sscc
Receiver DoSomething on dd
Receiver DoSomethingElse on ee
部分内容参考:命令模式