工厂方法是否适合我的问题设计?

时间:2010-04-26 07:26:09

标签: c++ factory-pattern factory-method

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

有一个基类和很多子类。

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

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

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

4 个答案:

答案 0 :(得分: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结构来避免一些内存碎片。

与往常一样,阅读您正在使用的模式是一个好主意。以下是Factory Method Pattern上的维基百科文章。

您还应该查看Boost Serialization库。它可以帮助您跨不同字节序和字大小的系统序列化数据。我上面详述的方法非常简单,并没有处理类似的东西。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

如果我理解正确,你当前的实现是容易出错的,有很多松散的目标,比如双方的处理器架构,因此,恕我直言,CORBA更适合你的情况。或者至少您可以使用一些表示法来传输数据。转移后,我可以建议Prototype和Visitor模式来创建和初始化您的对象。希望它有所帮助。

答案 3 :(得分:0)

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