<分区>
这是我的问题,我正在考虑在 C++ 中使用工厂方法,您有什么意见?
有一个基类和很多子类。
我需要通过 TCP 在网络上传输对象。
我将在第一端创建对象,并使用该对象创建一个字节数组 TCP 消息,并将其发送到另一端。
另一方面,我将分解 TCP 消息,创建对象并将该对象添加到多态队列中。
<分区>
这是我的问题,我正在考虑在 C++ 中使用工厂方法,您有什么意见?
有一个基类和很多子类。
我需要通过 TCP 在网络上传输对象。
我将在第一端创建对象,并使用该对象创建一个字节数组 TCP 消息,并将其发送到另一端。
另一方面,我将分解 TCP 消息,创建对象并将该对象添加到多态队列中。
最佳答案
简短回答:是的。
长答案:工厂方法模式就是你想要的。
您的网络消息需要在消息 header 中包含要反序列化的对象的类型和大小,然后在接收方,您的工厂方法可以使用和反序列化消息正文的其余部分以构造对象。
让这一切变得简单的一个好策略是让您的所有类存储数据,这些数据将在私有(private)结构中序列化并通过网络发送。其他非序列化类数据将在此结构之外。这样你就可以用最少的工作将整个结构转储到网络上。显然,如果您要跨平台(即,从大到小或从小到大端),您可能必须考虑字节顺序。
类似这样的事情(我敢肯定这远非完美,因为我只是想把它写下来):
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 结构。
与往常一样,仔细阅读您正在使用的模式是个好主意。这是关于 Factory Method Pattern 的维基百科文章.
您还应该查看 Boost Serialization图书馆。它将帮助您跨具有不同字节序和字长的系统序列化数据。我上面详述的方法非常简单,不会处理类似的问题。
关于c++ - 工厂方法是否适合我的问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2711704/