Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing factory pattern with different return types

I'm trying to implement a factory pattern and I ran into a problem. I try to make my classes simple here. Basically I have a base Packet class (PacketHeader) with some fields and methods. Also I have so many derived packet classes such as: InfoPacket1011, UsagePacket1011, InfoPacket1014, UsagePacket1014 and they all inherit from PacketHeader base class.

As you can see each packet has a version and my goal is to handle this packets based on their versions. So I should have two derived class, one for 1011 and one for 1014.

The base class (which itself is a derived class!) looks like this:

public abstract class PacketHandlerBase : Engine
{
    public abstract bool SendInfoPacket(int someInt, string someInput);
    public abstract List<???> BuildInfoPacket(string someInput);

    public abstract bool SendUsagePacket(int someInt, string someInput);
    public abstract List<???> BuildUsagePacket(string someInput);
    //...
    //...
    //...
}

My problem is that for methods such as BuildInfoPacket and BuildUsagePacket I have to return a List of that type. So in the derived classes I could have:

public class PacketHandler1011 : PackerHandlerBase
{
    //...
    public override bool SendInfoPacket(int someInt, string someInput);
    {
        // code implementation
        // return true or false
    }

    public override List<InfoPacket1011> BuildInfoPacket(string someInput);
    {
        // code implementation
        // return List<InfoPacket1011>
    }
}

public class PacketHandler1014 : PackerHandlerBase
{
    //...
    public override bool SendInfoPacket(int someInt, string someInput);
    {
        // code implementation
        // return true or false
    }

    public override List<InfoPacket1014> BuildInfoPacket(string someInput);
    {
        // code implementation
        // return List<InfoPacket1014>
    }
}

I don't know what to use in the PacketHandlerBase class to be able to override it in the derived classes. I guess I need generic methods and interface for that, but not sure how to handle that.

[Edit]: I fixed first part of my questions about packet inheritance. Thank you all for your answers, I read them and tell you if they work.

[Answer]: Thank you everyone for your prompt responses. I fixed the problem by passing List and by casting it in the method and in the caller. Well my code was much more complex than what I provided here and I just finished modifying it. I changed the pattern to abstract factory too to fix some other problems.

Any help would be greatly appreciated. Thanks in advance

like image 379
Kian Avatar asked Sep 16 '25 23:09

Kian


1 Answers

You are implementing in fact an Abstract Factory pattern where PackerHandlerBase is an Abstract Factory and it produces/builds an Abstract Product which in your case is an InfoPacket and UsagePacket. Concrete Factory is PacketHandler1011 or PacketHandler1014. And Concrete Product is InfoPacket1011 or InfoPacket1014 and so on.

So it should be:

public abstract class PacketHandlerBase : Engine
{
    public abstract bool SendInfoPacket(int someInt, string someInput);
    public abstract List<InfoPacket> BuildInfoPacket(string someInput);

    public abstract bool SendUsagePacket(int someInt, string someInput);
    public abstract List<UsagePacker> BuildUsagePacket(string someInput);
    //...
}

public class InfoPacket1014 : InfoPacket
{ 
    ///...
}

public class PacketHandler1011 : PackerHandlerBase
{
    //...
    public override List<InfoPacket> BuildInfoPacket(string someInput);
    {
        // code implementation
        return new List<InfoPacket> { new InfoPacket1011(), ... };
    }
}
like image 88
Konrad Kokosa Avatar answered Sep 19 '25 13:09

Konrad Kokosa