从接收器发送类的去耦命令(模式)?

时间:2012-08-03 00:56:14

标签: c# design-patterns

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

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

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

我对事件系统的最大关注是,从我对事件系统的经验来看,为了让发送者和接收者在不知道彼此的情况下进行交互而编写的代码量是疯狂的,并且根本不可行 - 我想要的每种方法一个事件可以访问,要求我修改至少一个其他类,通常更多,这会产生与紧密耦合的spegetti代码一样糟糕的问题。此外,我通常需要课程来发送对事件的响应,这也非常麻烦。

3 个答案:

答案 0 :(得分:4)

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

命令模式的作用是将实现与执行命令的类分离。创建命令后,可以将其传递到UI层或通过网络传递给远程客户端,执行类不需要知道命令的实现方式。

答案 1 :(得分:1)

首先,不要使用外观。如果您从一开始就在设计中使用外观,则可能需要重新考虑您的设计。 façade的主要目的是隐藏您希望简化交互的代码 - 通常是遗留代码。理想情况下,新代码应该从一开始就设计得更简单。

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

  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);
    

    这是一个过于简单化的示例,但说明了如何使行为像命令一样,但不需要完整的对象。

答案 2 :(得分:1)

你可以拥有

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

当然,这需要一些路由代码才能将命令从发行者转移到接收者。但是如果你将这个路由建立在约定基础之上,那么写一次代码应该不那么难。

(我基于这样的想法,即命令应该有单一的,定义明确的消费者。如果不是这样,那么这可能是一个事件,而且有点不同,因为有兴趣的人正在订阅他们自己的事件。)