Design Pattern: Visitor Pattern

Visitor pattern (Visitor): Represents an operation that acts on each element in an object structure. It allows you to define new operations that act on these elements without changing the class of each element.


      The visitor pattern is suitable for systems with relatively stable data structures.

      It decouples the data structure from the operations acting on the structure, allowing the set of operations to evolve relatively freely.

      The purpose of the visitor pattern is to separate the processing from the data structure. Many systems can be separated according to the algorithm and the data structure. If such a system has a relatively stable data structure and an algorithm that is easy to change, the use of the visitor pattern is relatively Appropriate. Because the visitor pattern makes it easy for algorithms to manipulate variables.

      The advantage of the visitor pattern is that it is easy to add new operations, because adding a new operation means adding a new visitor, the visitor pattern centralizes the relevant behavior into a visitor object.

The disadvantage of the visitor is that it makes it difficult to add new data structures.

base code

The Visitor class declares a Visit operation for each class of ConcreteElement in the object structure

abstract class Visitor{
    public abstract void VisitConcreteElementA(ConcreteElementA concreteElementA);

    public abstract void VisitConcreteElementB(ConcreteElementB concreteElementB);
}

ConcreteVisitor1 and ConcreteVisitor2 classes, specific access classes, implement each operation declared by the Visitor, each operation implements a part of the algorithm, and the algorithm fragment is the class corresponding to the object in the structure,

class ConcreteVisitor1 implements Visitor{
    public void VisitConcreteElementA(ConcreteElementA concreteElementA){
        System.out.println("被访问",concreteElementA.GetType().Name,this.GetType().Name)
    }

    public void VisitConcreteElementB(ConcreteElementB concreteElementB){
        System.out.println("被访问",concreteElementB.GetType().Name,this.GetType().Name)
    }
}

class ConcreteVisitor2 implements Visitor{
    public void VisitConcreteElementA(ConcreteElementA concreteElementA){
        System.out.println("被访问",concreteElementA.GetType().Name,this.GetType().Name)
    }

    public void VisitConcreteElementB(ConcreteElementB concreteElementB){
        System.out.println("被访问",concreteElementB.GetType().Name,this.GetType().Name)
    }
}

The Element class defines an Accept operation that takes a visitor as a parameter

abstract class Element{
    public abstract void Accept(Visitor visitor);
}

ConcreteElementA and ConcreteElementB classes, concrete elements, implement the Accept operation

class ConcreteElementA implements Element{
    //Make full use of double dispatch technology to realize the separation of processing and data structure
    public void Accept(Visitor visitor){
        visitor.VisitConcreteElementA(this);
    }

    //other related methods
    public void OperationA(){}
}

class ConcreteElementB implements Element{
    //Make full use of double dispatch technology to realize the separation of processing and data structure
    public void Accept(Visitor visitor){
        visitor.VisitConcreteElementB(this);
    }

    //other related methods
    public void OperationB(){}
}

The ObjectStructure class, which can enumerate its elements, can provide a high-level interface to allow visitors to access its elements

class ObjectStructure{
    private IList<Element> elements =  new List<Element>();

    public void Attach(Element element){
        elements.Add(element);
    }
    public void Detach(Element element){
        elements.Remove(element);
    }
    public void Accept(Visitor visitor){
        foreach(Element e in elements){
            e.Accept(visitor);
        }
    }
}

client code

ObjectStructure o = new ObjectStructure();
o.Attach(new ConcreteElementA());
o.Attach(new ConcreteElementB());

ConcreteVisitor1 v1 = new ConcreteVisitor1();
ConcreteVisitor1 v2 = new ConcreteVisitor2();

o.Accept(v1);
o.Accept(v2);


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325641927&siteId=291194637