当前位置:  开发笔记 > 编程语言 > 正文

命令模式:如何将参数传递给命令?

如何解决《命令模式:如何将参数传递给命令?》经验,为你挑选了6个好方法。

我的问题与命令模式有关,我们有以下抽象(C#代码):

public interface ICommand
{
    void Execute();
}

让我们来看一个简单的具体命令,它旨在从我们的应用程序中删除一个实体.Person例如,一个实例.

我会有一个DeletePersonCommand实现的ICommand.此命令需要Person删除作为参数,以便在Execute调用方法时将其删除.

管理参数化命令的最佳方法是什么?在执行参数之前如何将参数传递给命令?



1> Blair Conrad..:

您需要通过构造函数或setter注入(或等效项)将参数与命令对象相关联.也许是这样的:

public class DeletePersonCommand: ICommand
{
     private Person personToDelete;
     public DeletePersonCommand(Person personToDelete)
     {
         this.personToDelete = personToDelete;
     }

     public void Execute()
     {
        doSomethingWith(personToDelete);
     }
}


正是我要做的.对于构造命令时未知的任何内容,我将接口传递给在执行命令时获取对象的服务.这可能是代表或lambda exssion或其他对象.

2> Scott Stanch..:

通过构造函数或setter传递数据,但需要命令的创建者知道命令所需的数据...

"上下文"的想法非常好,我正在研究(一个内部的)框架,利用它一段时间.

如果设置控制器(与用户交互的UI组件,CLI解释用户命令,解释传入参数和会话数据的servlet等)以提供对可用数据的命名访问,命令可以直接询问他们想要的数据.

我真的很喜欢分离这样的设置允许.考虑分层如下:

User Interface (GUI controls, CLI, etc)
    |
[syncs with/gets data]
    V
Controller / Presentation Model
    |                    ^
[executes]               |
    V                    |
Commands --------> [gets data by name]
    |
[updates]
    V
Domain Model

如果您"正确"执行此操作,则相同的命令和表示模型可以与任何类型的用户界面一起使用.

更进一步,上面的"控制器"非常通用.UI控件只需要知道名称它们将调用的命令 - 它们(或控制器)不需要知道如何创建该命令或命令需要什么数据.这是真正的优势.

例如,您可以保存要在Map中执行的命令的名称.每当组件被"触发"(通常是actionPerformed)时,控制器会查找命令名称,实例化它,调用execute,并将其推送到撤消堆栈(如果使用的话).



3> Juanma..:

有一些选择:

您可以通过属性或构造函数传递参数.

其他选择可能是:

interface ICommand
{
    void Execute(T args);
}

并将所有命令参数封装在值对象中.


上面代码的问题是不同的命令(例如CreateSomeThingCommand和DeleteSomethingCommand)可能需要不同的参数,并且不能再以相同的方式执行(考虑IEnumerable .Execute()调用).命令模式用于将定义与执行分开...如果在执行时传递参数,则在执行时更改/控制命令的行为而不是定义时间.

4> jop..:

在创建命令对象时传递此人:

ICommand command = new DeletePersonCommand(person);

这样当你执行命令时,它已经知道它需要知道的一切.

class DeletePersonCommand : ICommand
{
   private Person person;
   public DeletePersonCommand(Person person)
   {
      this.person = person;
   }

   public void Execute()
   {
      RealDelete(person);
   }
}



5> bloparod..:

我的实现是这样的(使用Juanma提出的ICommand):

public class DeletePersonCommand: ICommand
{
    public DeletePersonCommand(IPersonService personService)
    {  
        this.personService = personService;
    }

    public void Execute(Person person)
    {
        this.personService.DeletePerson(person);
    }
}

IPersonService可以是一个IPersonRepository,它取决于你的命令是什么"层".



6> 小智..:

在这种情况下,我们对Command对象所做的就是创建一个Context对象,该对象本质上是一个地图。该映射包含名称/值对,其中键是常量,而值是Command实现使用的参数。如果您拥有一个命令链,其中以后的命令依赖于先前命令的上下文更改,则特别有用。

所以实际的方法变成

void execute(Context ctx);

推荐阅读
依然-狠幸福
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有