Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何避免使用方法参数违反Open Closed?_C#_Design Patterns_Language Agnostic_Open Closed Principle - Fatal编程技术网

C# 如何避免使用方法参数违反Open Closed?

C# 如何避免使用方法参数违反Open Closed?,c#,design-patterns,language-agnostic,open-closed-principle,C#,Design Patterns,Language Agnostic,Open Closed Principle,在下面的代码中,MessageProcessor类违反了开闭原则-每个新的IMessage实现都需要对此类进行更改。对于这种不违反O/C的场景,是否有一个很好的干净模式 public interface IMessage { } public class BlahMessage : IMessage { } public class MoohMessage : IMessage { } public class MessageStream { public void Dispatc

在下面的代码中,
MessageProcessor
类违反了开闭原则-每个新的IMessage实现都需要对此类进行更改。对于这种不违反O/C的场景,是否有一个很好的干净模式

public interface IMessage
{
}

public class BlahMessage : IMessage
{
}

public class MoohMessage : IMessage
{
}

public class MessageStream
{
    public void Dispatch(IMessage message)
    {
        var messageProcessor = new MessageProcessor();
        messageProcessor.Handle(message);
    }
}

public class MessageProcessor
{
    public void Handle(IMessage message)
    {
        if (message is MoohMessage)
            Handle((MoohMessage)message);

        if (message is BlahMessage)
            Handle((BlahMessage)message);
    }

    private void Handle(MoohMessage moo)
    {
    }

    private void Handle(BlahMessage blah)
    {
    }
}

这里的问题是,MessageProcessor类试图实现不同消息类的行为

相反,您可以将Process()方法添加到IMessage,并在每个消息类中实现它

所以界面看起来像

public interface IMessage
{
   Process();
}
并且,Dispatch方法可以直接调用该方法

public void Dispatch(IMessage message)
{
  message.Process();
}

您当前的
MessageProcessor
是否因为处理多种消息而违反了SRP

这里有一个可以考虑的选项:

  • 更改MessageStream以向调度程序发送消息
  • 创建不同的消息处理类
  • 在运行时向调度程序注册每个消息处理器
  • 调度器将消息路由到正确的处理器

当然,这种方法可能只是将OCP问题转移到另一个地方,在那里创建MessageProcessor实例并使用Dispatcher注册。但是如果(消息是XXX)调用,至少它会清理掉许多

除了签名,
句柄(MoohMessage moo)
句柄(BlahMessage blah)
有什么不同?这些是否应该在单独的类中(可能是泛型的)?为什么
处理方法需要不同?乍一看,逻辑应该在消息本身,而
MessageProcessor
应该只调用
IMessage
上的泛型方法来调用它。为什么不将Process()方法添加到IMessage并调用message.Process(),而不是MessageProcessor.Handle(message)?@MVarman,回答您的评论。这就是答案。消息只是愚蠢的DTO,毕竟它们是消息,它们本身不会有Process()方法。但这违反了SRP,而SRP可能更糟糕。信息就是那些信息。它们不包含处理自身所需的逻辑,这甚至没有意义。我没有意识到消息对象是普通的DTO。如果是这种情况,另一个选项是创建IMessageProcessor并实现IBlahMessageProcessor和IMoohMessageProcessor。然后,您可以将IMessageProcessor对象注入Dispatch()方法,或者使用工厂模式创建处理器对象(如果您不介意的话)。。是的,我想在某个时候,除非你使用DI容器自动连接处理程序,否则你将违反SRP。。。谢谢:)