命令设计模式 - 允许不同的具体命令返回不同的类型

时间:2013-08-15 09:47:00

标签: c# design-patterns return-value

我们正在设计一个新组件并考虑使用命令设计模式。

我们有两种主要类型的命令可以实现我们的IOurCommand接口(其他命令将继承该接口)。

问题是第一个命令CommandDoUpdates不需要返回任何值,而第二个命令CommandGetData是获取数据,所以它需要返回一些List对象(List<DataRow>

我们正在考虑处理这种情况:

  1. 返回一个类,其中包含有关操作成功的指示(奖励)和一个对象列表,这些对象将成为所有CommandDoUpdates的空列表。
  2. 保持List作为具体命令的成员 - 潜在的解决方案,但由于其他原因(浅拷贝与深拷贝等)使我们的生活更加艰难。
  3. 与#1相同,但在函数中返回一个基类,并且每个调用calss都必须将结果向下转换为具体类(Down cast不是一个好习惯,因为客户端需要知道什么是实际回报值)。
  4. 将命令分成两个不同的层次结构(一个返回一个值而一个不返回值),并使用两个不同的接收器 - 我真的不喜欢它,但它是一个选项。
  5. This帖子很好地解读了命令是否应该返回值/状态。这是相关的,因为在GoF书中,Command设计模式没有返回值。

    我的实际问题是:

    • 你能想到更好的解决方案吗?
    • 选项1,2和3的任何优缺点,选项4的任何优点?

    谢谢!

2 个答案:

答案 0 :(得分:0)

我怀疑命令模式正在扩展到它真正打破了这里的模式。你链接的帖子中的一条评论说得很好:“这种模式的初衷是有一些对象执行命令,但不知道它们实际上做了什么。”如果一个命令系列要访问数据而另一个命令系列要改变它,是否真的有一个常见的用例需要将它们抽象为一个普通类型?对我来说,一个通用的界面说两个对象的使用方式相同,但实际情况并非如此。

就更好的解决方案而言,一个常见的解决方案是使用MV *(MVC,MVP,MVVM)模式并让命令更新模型并在更新发生后通知观察者。

如果MV *对你来说太多的模式,那么我认为4是你的答案,只是摆脱了常见的界面。您不一定要有两个接收器,因为您可以使接收器上的方法通用。但是,我认为你必须做一些不同的事情,这取决于你是在处理CommandDoUpdates还是CommandGetData,所以方法的重载可能比检查“命令”的返回类型更清楚。我认为在这种情况下更明确的是让接收器的签名表示它从两种不同类型的对象获取消息,而不是说这些“命令”基本上是相同的类型。

另外,CommandDoUpdates可能更适合作为事务脚本,而CommandGetData作为存储库更好,并且可以重命名这两个层次结构?关于什么在上下文中首先引导你进入命令模式的信息并没有太多信息,只是因为它不是正确的选择,所以也许我完全不在这里。

答案 1 :(得分:0)

作为替代方案,您可以使Command必须返回结果:

  • 通知观察员,或
  • 将结果保存在可通过getter检索的成员中

我认为当您创建该特定命令时,您知道那种类型,因此您可以在命令完成后为其分配观察者或得到它的结果。