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

#include <algorithm>
#include <cassert>
#include <functional>
#include <iterator>
#include <list>
#include <string>

namespace Xml
{

class Node
{
public:
    explicit Node(const std::string &n) : m_name(n) { assert(!n.empty()); }
    Node(const Node&) = delete;
    Node& operator=(const Node&) = delete;

public:
    const std::string& get_name() const { return m_name; }

    void set_name(const std::string &n)
    {
        assert(!n.empty());
        m_name = n;
    }

public:
    virtual void to_string(std::string &s) const = 0;
    virtual Node* copy() const = 0;
    virtual ~Node() { }

private:
    std::string m_name;
};

class SimpleNode
    : public Node
{
public:
    SimpleNode(const std::string &n, const std::string &v)
        : Node(n)
        , m_value(v)
    { assert(!n.empty()); }

    SimpleNode(const SimpleNode&) = delete;
    SimpleNode& operator=(const SimpleNode&) = delete;

public:
    const std::string& get_value() const { return m_value; }

    void set_value(const std::string &v) { m_value = v; }

public:
    void to_string(std::string &s) const
    {
        assert(s.empty());
        assert(!get_name().empty());
        const std::string &v = get_value();
        s = "<" + get_name() +
            (v.empty() ? "/" : ">" + v + "</" + get_name()) + ">";
    }

    SimpleNode* copy() const
    {
        assert(!get_name().empty());
        return new SimpleNode(get_name(), get_value());
    }

private:
    std::string m_value;
};

class ComplexNode
    : public Node
{
private:
    explicit ComplexNode(const std::string &n) : Node(n) { assert(!n.empty()); }
    ComplexNode(const ComplexNode&) = delete;
    ComplexNode& operator=(const ComplexNode&) = delete;

    template<typename I>
    ComplexNode(const std::string &n, I b, I e)
        : Node(n)
        , m_child_nodes(b, e)
    { assert(!n.empty()); }

public:
    typedef std::list<Node*> ChildNodes;

    const ChildNodes& get_child_nodes() const { return m_child_nodes; }

    void append_node(Node *n)
    {
        assert(n != 0);
        m_child_nodes.push_back(n); 
    }

    void remove_node(Node *n)
    {
        assert(n != 0);
        ChildNodes &c = m_child_nodes;
        ChildNodes::iterator i = std::find(c.begin(), c.end(), n);
        if (i != c.end()) {
            c.erase(i);
        }
    }

public:
    void to_string(std::string &s) const
    {
        assert(s.empty());
        assert(!get_name().empty());
        std::string c;
        children_to_string(c);
        s = "<" + get_name() +
            (c.empty() ? "/" : ">" + c + "</" + get_name()) + ">";
    }

    ComplexNode* copy() const
    {
        assert(!get_name().empty());
        ChildNodes c;
        copy_children_to(c);
        return new ComplexNode(get_name(), c.begin(), c.end());
    }

private:
    void children_to_string(std::string &s) const
    {
        assert(!s.empty());
        const ChildNodes &c = get_child_nodes();
        ChildNodes::const_iterator b = c.begin();
        for ( ; b != c.end(); ++b) {
            std::string t;
            (*b)->to_string(t);
            s += t;
        }
    }

    void copy_children_to(ChildNodes &c) const
    {
        assert(c.empty());
        const ChildNodes &t = get_child_nodes();
        std::transform(t.begin(), t.end(), std::back_inserter(c),
                       std::mem_fn(&Node::copy));
        assert(c.size() == t.size());
    }

private:
    ChildNodes m_child_nodes;
};

}