C ++ design patterns - Visitor Pattern

Motivation
in the process of software to build, due to changes in demand, some of the class hierarchy is often necessary to add a new behavior (method), if doing so changes directly in the base class, it will bring very heavy subclasses change burden, even destroy the original design.
How without changing the premise of the class hierarchy at runtime for each class in the class hierarchy dynamically add new operations to transparently in order to avoid the above problems?
Pattern defines
represents an operation of each element of an object structure effect. May be defined such that the (extended) acting on the premise of the class does not change (stability) of each element in the operation of these elements letters (variation)
structure
QQ picture 20200214004135.png
ObjectStructure (object structure): to enumerate its elements, while providing a high level interface to this allows visitors to access its elements.
Examples

class Visitor;


class Element
{
public:
    virtual void accept(Visitor& visitor) = 0; //第一次多态辨析

    virtual ~Element(){}
};

class ElementA : public Element
{
public:
    void accept(Visitor &visitor) override {
        visitor.visitElementA(*this);
    }
    

};

class ElementB : public Element
{
public:
    void accept(Visitor &visitor) override {
        visitor.visitElementB(*this); //第二次多态辨析
    }

};


class Visitor{
public:
    virtual void visitElementA(ElementA& element) = 0;
    virtual void visitElementB(ElementB& element) = 0;
    
    virtual ~Visitor(){}
};

//==================================

//扩展1
class Visitor1 : public Visitor{
public:
    void visitElementA(ElementA& element) override{
        cout << "Visitor1 is processing ElementA" << endl;
    }
        
    void visitElementB(ElementB& element) override{
        cout << "Visitor1 is processing ElementB" << endl;
    }
};
     
//扩展2
class Visitor2 : public Visitor{
public:
    void visitElementA(ElementA& element) override{
        cout << "Visitor2 is processing ElementA" << endl;
    }
    
    void visitElementB(ElementB& element) override{
        cout << "Visitor2 is processing ElementB" << endl;
    }
};
        
    

        
int main()
{
    Visitor2 visitor;
    ElementB elementB;
    elementB.accept(visitor);// double dispatch
    
    ElementA elementA;
    elementA.accept(visitor);

    
    return 0;
}

Design pattern often say is: find and change package. Whether to adopt the visitor pattern, depends on "change" is. Visitor pattern, the "change" is the specific visitors, followed by the object structure; however, if a particular element will change, you can not use the visitor pattern, because it "affect the situation as a whole"
and therefore the biggest drawback of the Visitor pattern It is to extend the class hierarchy (add new Element subclasses), result in changes to Vistor class. Therefore Vistor mode is suitable for stable Element class hierarchy, the operation of which are often faced with frequent changes.

Guess you like

Origin www.cnblogs.com/Redwarx008/p/12306096.html