1

因此,为了在任何类中创建命令(基于模式),该类必须知道接收者类,以便将其传递给命令的构造函数,然后将类耦合在一起。有没有办法使用命令模式并保持两个类之间的间接度量?

我能想到的唯一解决方案是:

  • 使用调解器,但我不知道究竟如何,因为至少命令仍然需要传递给类,即使它只是它的接口
  • 使用外观,但这会将任何命令调用类耦合到外观
  • 使用事件系统而不是命令,但这在执行和编写代码本身方面有太多开销
  • 使用创建模式以某种方式创建命令,但将所有内容与该对象耦合

我对事件系统最大的担忧是,根据我在事件系统方面的经验,您必须编写大量代码才能让发送者和接收者在彼此不知情的情况下进行交互,这很疯狂而且根本不实用——我希望通过一个event 要求我修改至少一个其他类,通常更多,这会产生与紧密耦合的 spegetti 代码一样糟糕的问题。此外,我通常需要类来发送对事件的响应,这也很麻烦。

4

3 回答 3

4

命令模式并不意味着将创建者和接收者解耦。这些类通常已经耦合,甚至可能是同一个类。

命令模式所做的是将实现与执行命令的类分离。一旦创建了命令,就可以将它传递给 UI 层或通过网络传递给远程客户端,并且执行类不需要任何关于如何实现命令的知识。

于 2012-08-03T01:29:52.607 回答
1

首先,不要使用外观。如果您从一开始就在设计中添加外观,您可能需要重新考虑您的设计。外观的主要目的是隐藏您想要简化交互的代码——通常是遗留代码。理想情况下,新代码应该从一开始就使用更简单的界面来设计。

在不了解您的具体问题的情况下,我有一些建议:

  1. 继续使用事件系统。C# 有一个很棒的事件系统,您可以利用它而无需编写太多自己的代码;只需定义一些委托并添加事件处理程序,您就大功告成了。发送事件的机制被抽象出来,因此您的大部分工作就是将它们连接在一起。如果您以前没有经常使用事件,那么一些快速搜索应该会为您提供大量有用的信息。

  2. 在执行时指定接收者:

    public interface ICommand {
        public void Execute(IReceiver receiver);
    }
    

    这允许接收器在Execute()被调用时动态更改,这使得这种模式的使用可以作为在系统中传递行为的一种方式。但是,在这一点上,有一种更好的方法可以达到相同的结果......

  3. 传递函数,而不是对象。 C# 再次发挥作用,允许函数像任何其他数据类型一样在系统中传递。将您的命令指定为委托:

    class MyThing {
        public delegate void Command(IReceiver receiver);
    
        public static void PrintReceiver(IReceiver receiver){
             // print the receiver
        }
    
        public static void ChangeReceiver(IReceiver receiver){
             // change something about the receiver
        }
    }
    

    稍后允许您执行以下操作:

    IReceiver receiver = someReceiverThatAlreadyExists;
    Command action = someCondition ? MyThing.PrintReceiver : MyThing.ChangeReceiver;
    action(receiver);
    

    这是一个过于简单的示例,但说明了如何拥有类似于命令的行为,但不需要完整的对象。

于 2012-08-03T01:45:46.317 回答
1

你可以有

public interface ICommandHandler<T> where T : ICommand 
{
    void Execute(T command);
}

当然,这将需要一些路由代码来将您的命令从发布者传输到接收者。但是,如果您将此路由基于约定,那么编写一次的代码应该不会那么难。

(我的想法是命令应该有一个单一的、定义明确的消费者。如果不是这种情况,那么这可能是一个事件,这有点不同,因为有兴趣的各方正在订阅事件他们自己)。

于 2012-08-03T02:45:55.063 回答