工厂应该负责重新构造序列化的对象吗?
Should a factory take care of reconstructing serialized objects?
我正在做一个作业,其中我必须实现抽象工厂模式。我给了一个工厂类的模板,我需要实现(和调整),以使测试程序通过。
模板是这样的:
typedef Shape *(createShapeFunction)(void);
/* thrown when a shape cannot be read from a stream */
class WrongFormatException { };
class ShapeFactory
{
public:
static void registerFunction(const std::string &, const createShapeFunction *);
static Shape *createShape(const std::string &);
static Shape *createShape(std::istream &);
private:
std::map<std::string, createShapeFunction *> creationFunctions;
ShapeFactory();
static ShapeFactory *getShapeFactory();
};
createShape
方法的第一个重载是直接的,但是第二个重载用于要求工厂知道其产品是如何序列化的场景。
更精确地说:一堆带有随机参数的形状被生成,序列化到一个流,然后流被馈送到第二次重载,以便一个接一个地重建对象。
根据我对OOP的了解,这似乎是不对的,因为以这种方式反序列化对象意味着了解它们是如何序列化的,这不可避免地导致违反封装原则(通过将产品的实现细节泄露给工厂)。
这是正确的,或者也许我错过了什么?
我认为您的工厂类很好,并且没有违反任何SOLID OO设计原则。
工厂应该知道它创建的类有什么共同之处。换句话说:它知道基类不变量,包括表示有效对象的流标记。在输入错误时抛出异常是完全有效的。由于这些知识存储在注册表中,类本身不依赖于具体类,而只依赖于抽象基类(依赖反转原则)。
在编译时不知道的是整个类层次。这些知识只有在运行时通过注册表才能显示出来。这有效地将静态类型切换更改为动态映射查找,这是OO中多态性的首选使用,并且可以轻松构造新的子类,而无需修改工厂类(所谓的开/闭原则)。
我没有阅读分配,但认为您可能误解了第二个createShape的功能。如果不是,我很抱歉,但这就是我的想法。
第一个createShape获取一个键(形状名称),然后创建它。就像你说的,非常直接。
第二个createShape不接收一堆已经创建和序列化的形状(如您所描述的),而是一堆键。它获取一个包含键集合的流,然后遍历,创建所有相应的形状。我认为,它的意思是创造出大量的形状。
这可能是赋值的一部分,因此您可以显示您知道如何使用迭代器。
我会添加代码,但这将是作弊;)
- 提升反序列化对象具有 nan 或 -nan 值
- 在 cpp 中的平面缓冲区中序列化对象
- 将 boost 序列化对象的 asio::streambuf 表示转换为 Beast 的 DynamicBody req.body()
- 从一个文件中读取多个序列化对象
- 具有GSOAP的序列化对象,以验证Web服务输出
- 促进序列化对象为json
- 使用 FlatBuffers 序列化对象的向量
- 是否可以简单地序列化C++对象
- C 用向量序列化对象会导致双重自由损坏
- 用C++序列化对象的首选方式
- 序列化C++对象
- 如何在不存在任何数据损坏风险的情况下序列化对象
- 如何使用boost::序列化将对象的矢量作为属性序列化对象
- C++:如何在不使用库的情况下序列化/反序列化对象
- 写入函数是否在 C++ 中使用 ASCII 序列化对象
- 如何从 QDataStream 中读取多个相同类型的序列化对象
- 在C++中反序列化对象
- 在Qt中序列化对象图有哪些方法
- 使用 mixins 序列化/反序列化对象
- 序列化对象时丢失名称