我对命令模式的理解是,您只需拥有 1 个虚拟方法“execute()”,并且实现可能具有的所有依赖项都放在构造函数中或通过实现中的 setter 注入(如在此处讨论)。
但是,在该模式的 WPF 实现中,我注意到它们将通用参数传递给 execute() 函数(在此处解释)。
这对我来说似乎是对接口的污染,向execute() 函数添加通用参数的动机是什么?
规范命令模式通常用漂亮的自包含命令来说明。因为命令所需的任何信息都隐藏在 Command 对象实例中(通常通过参数化构造函数)。
但是在某些情况下,Execute 所需的参数可能在命令创建时不可用(仅在运行时才知道)。例如想象一个SignOutCommand( username )
. 用户名在用户首次登录后单击 SignOut 按钮时确定。
所以用户名作为通用参数传递给Command.Execute()
; 每个命令都可以自由定义其输入并相应地进行转换,例如,任意命令可能需要 5 个参数作为对象 []。
它用于数据绑定。例如,当您将命令绑定到列表中的每个对象时,当前实例将被发送到 execute 方法,这样您就不必自己跟踪当前实例。
也就是说,我不认为 WPF 命令概念是命令模式的实现,它们只是共享术语。
该参数背后的原因是命令创建者(知道需要执行什么命令)与调用者(知道何时需要执行命令)之间的隔离。
在某些命令中,创建者无法获得执行所需的某些信息。调用者通过传递参数来填充空白以执行。示例:创建者创建了一个命令,该命令根据某些标准过滤记录列表。该列表在创建站点不可用,因为应用程序中有多种列表。
调用者将通过作为参数传递来指定需要过滤的列表。
我们使用稍微改变的命令模式,因此除了 Execute 方法之外,我们还有两个属性 Request 和 Response ,我们使用多态性对它们进行参数化。
有什么问题:
public class DeleteCommand : BaseCommand
{
private Dictionary<string, object> parameters;
public DeleteCommand(Dictionary<string, object> parameters)
{
this.parameters = parameters;
}
public void Execute()
{
var person = (Person)parameters["Person"];
var salary = System.Convert.ToDouble(parameters["Salary"]);
// etc.
}
}
现在,如果您有一个收集参数的控制器,您可以将这些参数传递给您的命令。