Is the factory method correct for my problem?

here is my problem and I am thinking about using a factory method in C ++, what are your opinions?

There is a base class and many subclasses.

I need to transfer objects over a network over TCP.

I will create objects from the first side, and using this object, I will create a byte array TCP message and send it to the other side.

On the other hand, I will decompose the TCP message, I will create an object, and I will add that object to the polymorphic queue.

+2


a source to share


4 answers


Short answer: Yes.

Long answer: The factory method pattern is what you want.

Your network messages need to specify the type and size of the object to deserialize in the message header, and then on the receiver side, your factory method can use and deserialize the rest of the message body to create objects.

A good strategy to keep it simple is for all your classes to store data, which they will serialize and wire in a private structure. Other unserialized class data will be outside of this structure. This way you can simply dump the entire structure on the network with minimal work. Obviously, you might have to consider byte ordering considerations if you are moving to a cross platform (i.e. big to small or small to big end).

Something like this (I'm sure it's far from ideal since I'm just writing it from my head):



enum VehicleType  
{
  VehicleType_Car,
  VehicleType_Bike
};

class Vehicle 
{
   virtual size_t GetDataSize() = 0;
   virtual void* GetData() = 0;
};

class Bike : Vehicle
{
private:
    VehicleType _type;
    size_t _dataSize;
    struct BikeData
    {
       char[100] name;
       // etc 
    } _data;
public:
    Bike(void* data)
      : Bike(static_cast<BikeData*>(data)->name) 
    {
    }

    Bike(char[]& name) 
      : _type(VehicleType_Bike), _dataSize(sizeof(BikeData))
    {
       memset(&_data.name, 0, 99);
       strncpy(&_data.name, name, 99);
    }

    virtual size_t GetDataSize() { return _dataSize; }
    virtual void* GetData() { return &_data; }
};

class Car : Vehicle
{
    // etc
};


void SendVehicle(int socket, const Vehicle& vehicle)
{
    write(socket, vehicle.GetData(), vehicle.GetDataSize());  
}

Vehicle* ReceiveVehicle(int socket)
{
    VehicleType type;
    size_t dataSize;

    read(socket, &type, sizeof(VehicleType));
    read(socket, &dataSize, sizeof(size_t));

    BYTE* data = new BYTE[dataSize];
    read(socket, &data, dataSize);

    Vehicle v* = CreateVehicle(type, dataSize, data);
    delete[] data;

    return v;
}

// The factory method.
Vehicle* CreateVehicle(VehicleType type, size_t dataSize, void* data)
{
    switch(type)
    {
        case VehicleType_Car: return new Car(data);
        case VehicleType_Bike: return new Bike(data);
    }

    return 0;
}

      

You can even avoid memory fragmentation by using the buffer you are reading the cell as a Bike_data structure.

As always, reading on the template you are using is a good idea. Here is a Wikipedia article on Factory Method Pattern .

You should also look into the Boost Serialization library . This will help you serialize data across different systems with varying degrees of precision and word sizes. The method I detailed above is very simple and has nothing to do with this kind of thing.

+1


a source


The "Parametrized factory method" is a very powerful way to deserialize: get your object and let it deserialize based on its data.



0


a source


If I understood correctly, your current implementation is error prone, there are a lot of loose ends on both sides like processor architecture, so IMHO CORBA is better suited to your case. Or at least you can use some notation to convey data. Once passed, I can suggest the Prototype and Visitor templates for creating and initializing your objects. Hope it helps.

0


a source


Depending on your exact requirements, I would suggest using the Object-Request-Broker pattern found in the software architecture books.

0


a source







All Articles