Reputation: 1599
I have a hierarchy.
public interface IIncomingMessage : IMessage
{
String Source { get; set; }
void ProcessMessage();
}
public interface IOutgoingMessages : IMessage
{
void SendMessage();
}
I have a client that uses a Static CreateMessage method to generate my message.
IMessage message = MessageFactory.CreateMessage("incomingA");
messageA.ProcessMessage();
However the only way I can do this is if I add ProcessMessage() to IMessage. However if I do this then I must implement this in IOutgoingMessage.
Now as I write this I see that I could just get rid of IMessage.. should I? Or is there a better way of doing this?
Upvotes: 1
Views: 151
Reputation: 359
(assuming 'MessageFactory.CreateMessage("incomingA")' return an object of type IIncomingMessage)
either use var
var message = MessageFactory.CreateMessage("incomingA");
message.ProcessMessage();
or cast the result
IMessage message = MessageFactory.CreateMessage("incomingA");
if (!(message is IIncommingMessage))
throw new InvalidOperationException();
(message as IIncommingMessage).ProcessMessage();
Upvotes: 0
Reputation: 6468
You can use different classes which don't inherit anything and completely separate the process. If you do that you will loose several advantages of using subclassing in this case. There might be similar properties between them which will make it easier to reference one versus the other if they both extend a common class. As for your method issue with these subclasses, you can simply have your parent class declare a common method (let's call it ProcessMessage()
), and simply have each subclass overwrite the behavior of such method. This way you don't need to have to different methods but simply two different definitions. Simple polymorphism concepts.
Upvotes: 0
Reputation: 2306
I'll try to simplify by giving another example of this scenario:
public class Animal
{
void Run();
}
public class Giraffe : Animal
{
void ExtendNeck();
}
public class Monkey : Animal
{
void EatBanana();
}
Now is it okay if I now add EatBanana()
to Animal
? As you noticed yourself, not all IMessage
implementors ProcessMessage()
and in this example not all animals EatBanana()
. What is another way to accomplish what you are trying to do? Only use IMessage
if you do have common functionalities to be shared among your classes. If you don't have any, there is no need for an inteface. Have YAGNI in mind. You may add it later if there are common functionalities. If you want to create an IncomingMessage
and call IncomingMessage
specific methods, then just create a strongly typed IncomingMessage
and work with it. You may not even need a static factory method.
Upvotes: 1
Reputation: 28701
Based on how you're using the CreateMessage
factory, you are expecting that ProcessMessage
is a common method to all IMessage
types. Based on how you expect your code to work, I would say that IMessage
should have a ProcessMessage
method interface defined.
However, in looking at the small snippet of code, it seems to me that your intent is not to always process a message, but only do so if it's an IIncomingMessage
implementation. So your factory approach isn't going to work. T. Kiley's suggestion of having two factory methods of CreateInboundMessage
and CreateOutboundMessage
may make more sense since you have different behaviors for both types of messages. Those methods then would return IIncomingMessage
and 'IOutgoingMessage` instances and then you can process them or handle them accordingly.
IMessage
is being used, currently, as a marker interface. If you see a need for this - whether it's a constraint for generics (e.g. MyCollection<T> where T : IMessage
), then keep it. But if it's really not describing behavior or a common set of properties/methods or if it's not to be used as a useful marker, then I'm not sure what benefit it provides.
Again, this is based off just seeing a little bit of code. I'm assuming there's more behavior and functionality behind the scenes. Good luck!!
Upvotes: 4