# Visitor Design Pattern explained in 2 minutes

### Problem Statement

Consider the below `Animal` interface. If you want to add new methods to the interface, you have to update `Cow` and `Dog` classes to implement those methods.

```java
public interface Animal {
}

public class Cow implements Animal {
}

public class Dog implements Animal {
}
```

But what if you want to add new functionalities across all the classes without worrying about changing them, then Visitor Design Pattern is perfect for you.

```java
public interface Animal {
    <T> T accept(AnimalVisitor<T> visitor);
}

public class Cow implements Animal {
    @Override
    public <T> T accept(AnimalVisitor<T> visitor) {
        return visitor.visit(this);
    }
}

public class Dog implements Animal {
    @Override
    public <T> T accept(AnimalVisitor<T> visitor) {
        return visitor.visit(this);
    }
}
```

In the above scenario, let's say you want to add new functionality like `Speak` or `NumberOfLegs`, then you have to create an implementation of `AnimalVisitor` and implement your business logic directly in those classes.

```java
public interface AnimalVisitor<T> {
    T visit(Cow cow);

    T visit(Dog dog);
}

public class LegsVisitor implements AnimalVisitor<Integer> {
    @Override
    public Integer visit(Cow cow) {
        return 4;
    }

    @Override
    public Integer visit(Dog dog) {
        return 4;
    }
}

public class SpeakVisitor implements AnimalVisitor<String> {
    @Override
    public String visit(Cow cow) {
        return "Moo";
    }

    @Override
    public String visit(Dog dog) {
        return "Bark";
    }
}
```

Driver Code

```java
public class Main {
    public static void main(String[] args) {
        Animal cow = new Cow();
        Animal dog = new Dog();
        AnimalVisitor<Integer> legsVisitor = new LegsVisitor();
        AnimalVisitor<String> speakVisitor = new SpeakVisitor();

        System.out.println(cow.accept(legsVisitor));
        System.out.println(cow.accept(speakVisitor));
        System.out.println(dog.accept(legsVisitor));
        System.out.println(dog.accept(speakVisitor));
    }
}

Output:
4
Moo
4
Bark
```

### What's the benefit?

* If you refer to the code once more, then you will notice that we added new functionality to `Cow` and `Dog` class without changing it -- this functionality is critical when working with client libraries.
    
* All the business logic is encapsulated in Visitor classes, which can help in segregating domain logic from model classes e.g. `LegsVisitor` contains all the logic for calculating the number of legs for all types of animals.
    
* Adherence to Open-Closed Principle i.e. class is open to extension but closed for modifications.
    
* Adherence to the Single Responsibility Principle i.e. class has only one responsibility.
    

### What's the drawback?

* If you have a lot of sub-classes, then the Visitor implementation must handle them even if you want to add new functionality to only one of the classes.
    
* While adding a new class, you must update the existing visitor implementations to support the new class.
