3

我正在做一个作业,我必须在其中实现抽象工厂模式。我得到了一个工厂类的模板,我需要实现(和调整)它以使测试程序通过。

模板如下所示:

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 的了解,这似乎不正确,因为以这种方式反序列化对象意味着了解它们是如何序列化的,这不可避免地导致违反封装原则(将产品的实现细节泄露给工厂) .

这是对的还是我错过了什么?

4

2 回答 2

1

我认为您的工厂类很好,并且没有违反任何面向对象设计的SOLID原则。

工厂应该知道它创建的类有什么共同点。换句话说:它知道基类不变量,包括表示有效对象的流标记。在输入错误的情况下抛出异常是完全有效的。由于该知识存储在注册表中,因此类本身不依赖于具体类,而仅依赖于抽象基类(依赖倒置原则)。

它在编译时不知道的是整个类层次结构。该知识仅在运行时通过其注册表显而易见。这有效地将静态类型切换更改为动态映射查找,这是 OO 中多态性的首选使用,并且可以轻松构造新的子类,而无需修改工厂类(所谓的开放/封闭原则)。

于 2013-04-14T20:26:41.813 回答
0

I have not read the assignment, but think you might have misunderstood the function of the second createShape. If not, I apologize, but this is what I think.

The first createShape gets one single key (the shape name) and then creates it. Pretty straight forward as you said.

The second createShape does not receive a bunch of shapes already created and serialized (as you described) but a bunch of keys. It gets a stream that contains a collection of keys and then iterates over all of them creating all the respective shapes. It is meant, I think, to create shapes in bulk.

It is probably part of the assignment so you show you know how to use iterators.

I would add code, but it would be cheating ; )

于 2013-04-14T20:23:37.620 回答