5. Which design pattern is used in the following code?

#include <cassert>
#include <map>
#include <string>

class Document
{
public:
    virtual Document* clone() const = 0;
    virtual void to_string(std::string &s) const = 0;
    virtual ~Document() { }
};

class XmlDocument;

class ResumeDocument
    : public Document
{
public:
    ResumeDocument(const XmlDocument &d);
    ResumeDocument() = delete;
    ResumeDocument(const ResumeDocument&) = delete;
    ResumeDocument& operator=(const ResumeDocument&) = delete;

public:
    ResumeDocument* clone() const;
    void to_string(std::string &s) const;
};

class TableDocument
    : public Document
{
public:
    TableDocument(const XmlDocument &d);
    TableDocument() = delete;
    TableDocument(TableDocument&) = delete;
    TableDocument& operator=(TableDocument&) = delete;

public:
    TableDocument* clone() const;
    void to_string(std::string &s) const;
};

class DocumentManager
{
private:
    DocumentManager();
    DocumentManager(DocumentManager&) = delete;
    DocumentManager& operator=(DocumentManager&) = delete;

public:
    static DocumentManager& get_instance()
    {
        static DocumentManager m;
        return m;
    }

public:
    Document* create(const XmlDocument& d,
                     const std::string &n = std::string(""))
    {
        Document *a = 0;
        const std::string &t = get_document_type(d);
        if (t == "Resume") {
            a = new ResumeDocument(d);
        }
        else if (t == "Table") {
            a = new TableDocument(d);
        }
        if (a != nullptr && !n.empty()) {
            Document *c = a->clone();
            Name2Document::iterator i = m_name_to_document.find(n);
            if (i == m_name_to_document.end()) {
                m_name_to_document.insert(std::make_pair(n, c));
            }
            else {
                delete i->second;
                i->second = c;
            }
        }
        return a;
    }

    Document* create(const std::string& n)
    {
        assert(!n.empty());
        Document *a = nullptr;
        const Name2Document::const_iterator i = m_name_to_document.find(n);
        if (i != m_name_to_document.end()) {
            assert(i->second != nullptr);
            a = i->second->clone();
        }
        return a;
    }

private:
    static std::string get_document_type(const XmlDocument &d);

private:
    typedef std::map<std::string, Document*> Name2Document;
    Name2Document m_name_to_document;
};