Behavioral model -- visitor model

Posted by Das Capitolin on Wed, 26 Jan 2022 05:54:58 +0100

Visitor mode

1 Definition

Encapsulates some operations that act on each element in a data structure. It can define new operations that act on these elements without changing the data structure.

2 Structure

The visitor pattern contains the following main roles:

  • Abstract visitor role: defines the behavior of accessing each element. Its parameters are the accessible elements. Theoretically, the number of methods is the same as the number of element classes. From this point, it is not difficult to see that the visitor pattern requires that the number of element classes cannot be changed
  • Specific visitor role: give the specific behavior generated when accessing each element class
  • Abstract element role: defines a method to accept visitors. Its meaning means that every element can be accessed by visitors
  • Specific element role: provide the specific implementation of the access method, and this specific implementation usually uses the method provided by the visitor to access the element class
  • Object structure role: the object structure mentioned in the definition. The object structure is an abstract expression. Specifically, it can be understood as a class with container nature or object characteristics. It will contain a group of elements, and these elements can be iterated for visitors to access

3 Implementation

Feeding pets: now there are many people who have pets. Let's take this as an example. Of course, pets are also divided into dogs, cats, etc. if you want to feed pets, the owner can feed them, and others can feed them.

  • Abstract visitor role: the person who feeds the pet
  • Specific visitor roles: host, others
  • Abstract element character: Animal abstract class
  • Specific element roles: pet dog, pet cat
  • Structure object role: master home
//Abstract visitor role
public interface Person {
    //Feed the cat
    void feed(Cat cat);
    //feed a dog
    void feed(Dog dog);
}
//Abstract element role
public interface Animal {
    //Accept functions accessed by designated visitors
    void accept(Person person);
}
//Specific element character (CAT)
public class Cat implements Animal{
    @Override
    public void accept(Person person) {
        person.feed(this);
        System.out.println("Kittens eat food");
    }
}
//Specific element role (dog)
public class Dog implements Animal{
    @Override
    public void accept(Person person) {
        person.feed(this);
        System.out.println("Dogs eat food");
    }
}
//Specific visitor role (host)
public class Owner implements Person{
    @Override
    public void feed(Cat cat) {
        System.out.println("The owner feeds the cat");
    }

    @Override
    public void feed(Dog dog) {
        System.out.println("The owner feeds the dog");
    }
}
//Specific visitor roles (others)
public class Someone implements Person{
    @Override
    public void feed(Cat cat) {
        System.out.println("Others feed the cat");
    }

    @Override
    public void feed(Dog dog) {
        System.out.println("Other feeding dogs");
    }
}
//Object structure role
public class Home {
    //Declare a collection object to store elements
    private List<Animal> animals = new ArrayList<>();
    //Add element
    public void add(Animal animal){
        animals.add(animal);
    }
    
    public void action(Person person){
        //Traverse the collection, get each element, and let visitors access each element
        for (Animal animal : animals) {
            animal.accept(person);
        }
    }
}
//Test class
public class Test {
    public static void main(String[] args) {
        //Create home object
        Home home = new Home();
        //Add element
        home.add(new Dog());
        home.add(new Cat());
        //Create master
        Owner owner = new Owner();
        //Let the host feed
        home.action(owner);
    }
}

Test results:
The owner feeds the dog
Dogs eat food
The owner feeds the cat
Kittens eat food

4 advantages and disadvantages

advantage:

  • Good expansibility: add new functions to the elements in the object structure without modifying the elements in the object structure
  • Good reusability: define the general functions of the whole object structure through visitors, so as to improve the degree of reusability
  • Separate irrelevant behaviors: separate irrelevant behaviors through visitors, and encapsulate relevant behaviors to form a visitor, so that each visitor has a single function

Disadvantages:

  • It is difficult to change the object structure: in the visitor mode, each new element class is added with corresponding specific operations in each specific visitor, which violates the "opening and closing principle"
  • Violating the dependency inversion principle: the visitor pattern relies on concrete classes instead of abstract classes

5 usage scenarios

  • The object structure is relatively stable, but its operation algorithm often changes
  • The objects in the object structure need to provide a variety of different and irrelevant operations, and the changes of these operations should not affect the structure of the object

Topics: Design Pattern