Fiona
Fiona

Reputation: 1599

Interface inheriting interface

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

Answers (4)

tooslow
tooslow

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

A Salcedo
A Salcedo

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

Farhad Alizadeh Noori
Farhad Alizadeh Noori

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

David Hoerster
David Hoerster

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

Related Questions