0
\$\begingroup\$

We have a base interface:

        public interface IMessage
        { 
            //Some properties
        }

then we have derived messages that implement this interface such as:

        public class AlarmEventMessage: IMessage 
        {   //Some properties  }

Now, these messages get routed to a message handler that receives them. So we have multiple overloads for this Handle(IMessage message) to handle the specific derived messages.

        public class MessageHandler
        {
             public bool Handle(IMessage message)
             {
                 if (message is AlarmEventMessage)
                 {
                     return Handle(message as AlarmEventMessage);
                 }
                 // some more message routing here
             }

             public bool Handle(AlarmEventMessage message)
             {
                 // Some business logic here
             }

             //Handle more messages here
        }

I believe it violates the Single-Responsibility Principle. This class constantly keeps changing because of new messages being added and also the business logic that relates with this new message.

Are there any other SOLID principles it violates? Does it look like an Anti-Pattern?

\$\endgroup\$
  • 1
    \$\begingroup\$ Welcome to Code Review! Your current question touches on a typical gray area of Code Review. We're not very fond of "example code" around here, the only question then is what "example code" is :) Either way, I hope the next time you ask a question here you will provide some more context and more real code. For more information, see this meta question \$\endgroup\$ – Simon Forsberg Jul 3 '14 at 15:29
3
\$\begingroup\$

You are correct when you say that the MessageHandler class violates the Single Responsibility Principle.

What you're looking for here is generics. First of all, you need to define a contract for messages and their respective handlers. This can be done with the following:

public interface IMessage
{
    // properties
}

public interface IMessageHandler<in TMessage>
    where TMessage : IMessage
{
    bool Handle(TMessage message);
}

So with the AlarmEventMessage, you can do this:

public class AlarmEventMessage : IMessage
{
    // properties
}

public class AlarmEventMessageHandler : IMessageHandler<AlarmEventMessage>
{
    public bool Handle(AlarmEventMessage message)
    {
        // stuff
    }
}

This design allows you to do some cool stuff with decorator chains, dispatching, registration by convention (if you're using an IoC container that supports it), among other things. For more information, check out the following two articles (they demonstrate how to implement the command/query pattern, but the design is identical):

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.