2

这是我的问题,我正在考虑在 C++ 中使用工厂方法,你有什么意见?

有一个基类和许多子类。

我需要通过 TCP 在网络上传输对象。

我将在第一侧创建对象,并使用该对象创建一个字节数组 TCP 消息,并将其发送到另一侧。

另一方面,我将分解 TCP 消息,创建对象并将该对象添加到多态队列中。

4

4 回答 4

1

简短的回答:是的。

长答案:工厂方法模式就是你想要的。

您的网络消息需要在消息头中包含要反序列化的对象的类型和大小,然后在接收方您的工厂方法可以使用和反序列化消息正文的其余部分以构造对象。

一个简单的好策略是让你的所有类都将它们将要序列化并通过网络发送到私有结构中的数据存储起来。其他非序列化的类数据将在此结构之外。这样你就可以用最少的工作将整个结构转储到网络上。显然,如果您要跨平台(即从大到小或从小到大字节序),您可能必须考虑字节顺序。

像这样的东西(我确信这远非完美,因为我只是把它写在我的脑海中):

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;
}

您甚至可以通过使用从套接字读取的缓冲区作为Bike 的 _data 结构来避免一些内存碎片。

与往常一样,阅读您正在使用的模式是一个好主意。这是关于工厂方法模式的维基百科文章。

您还应该查看Boost 序列化库。它将帮助您跨具有不同字节顺序和字长的系统序列化数据。我上面详述的方法非常简单,不处理这样的事情。

于 2010-04-27T15:46:15.037 回答
0

“参数化工厂方法”是一种非常强大的反序列化方式:获取您的对象并让它根据其数据进行反序列化。

于 2010-04-26T07:47:23.887 回答
0

如果我理解正确,您当前的实现很容易出错,双方都有许多松散的末端,例如处理器架构,因此,恕我直言,CORBA 更适合您的情况。或者至少您可以使用一些符号来传输数据。转移后,我可以建议使用原型和访问者模式来创建和初始化您的对象。希望能帮助到你。

于 2010-04-26T08:35:04.443 回答
0

根据您的确切要求,我建议使用 Object-Request-Broker 模式,该模式可以在面向模式的软件架构书籍中找到。

于 2010-04-26T16:15:57.627 回答