opencodez

Java Behavioral Design Patterns – Visitor Design Pattern

In this article, we will go through another pattern from behavioral category: Visitor Design Pattern.

The visitor design pattern is generally used when you have to do an operation on heterogeneous objects. The operation being performed is kept in different class and the objects of classes that need to be operated upon are passed to this method. This pattern can be used when you see:

xHere are ALL other Java Design Patterns, explained in detail with examplesx

Visitor Design Pattern by Example

To understand the pattern we will consider a real-world problem of Taxi Transport. In this, a taxi can transport persons, animals, and luggage. Based on type its fare may vary. We will apply Visitor Pattern to calculate total fare of the taxi.

Let us define a Transportable interface that will be implemented by each of the types that can be transported in a taxi.

public interface Transportable {
	public void accept(Visitor v);
}

Now we will define Visitor interface

public interface Visitor {
	public void visit(Person p);
	public void visit(Animal a);
	public void visit(Luggage l);
}

Note our Visitor interface has visit method for each of the type it is going to process.

The different types are implemented as

Person

public class Person implements Transportable {

	private double fare;
	private int numberOfPersons;
	
	public Person(double f, int n) {
		fare = f;
		numberOfPersons = n;
	}
	
	@Override
	public void accept(Visitor visitor) {
		visitor.visit(this);
	}
        
        //Getters //Setters
}

Animal

public class Animal implements Transportable {

	private double fare;
	private int numberOfAnimals;
	
	public Animal(double f, int n) {
		fare = f;
		numberOfAnimals = n;
	}	

	@Override
	public void accept(Visitor visitor) {
		visitor.visit(this);
	}

	//Getters //Setters
}

Luggage

public class Luggage implements Transportable {

	private double fare;
	private double weight;
	
	public Luggage(double f, double w) {
		fare = f;
		weight = w;
	}		

	@Override
	public void accept(Visitor visitor) {
		visitor.visit(this);
	}

	//Getters //Setters
}

The concrete class which implements the Visitor interface does all the processing on each of the types

public class Taxi implements Visitor {
	
	private double totalFare;

	@Override
	public void visit(Person p) {
		totalFare = totalFare + (p.getFare() * p.getNumberOfPersons());
	}

	@Override
	public void visit(Animal a) {
		totalFare = totalFare + (a.getFare() * a.getNumberOfAnimals());	
	}

	@Override
	public void visit(Luggage l) {
		totalFare = totalFare + (l.getFare() * l.getWeight());
	}

	public double getTotalFare() {
		return totalFare;
	}
	
}

Running the Example

public class TaxiBilling {
	
	public static void main(String args[]) {
		
		ListxTransportablex list = new ArrayListxTransportablex();
		
		list.add(new Person(12.4f, 1));
		list.add(new Animal(24.5f, 1));
		list.add(new Luggage(10.9f, 5));
		
		Taxi taxi = new Taxi();
		for(Transportable t : list) {
			t.accept(taxi);
		}
		
		System.out.println(String.format("Total Fare : $%.2f", taxi.getTotalFare()));
		
	}

}

See how our demo is iterating through all the transportable items and executing accept method.

Output

Total Fare : $91.40

Advantages

Disadvantages

Conclusion

In this article, we understood Visitor Design Patter with the help of a simple example. The source code is available in our Github repository.

Download Code

x

xHere are ALL other Java Design Patterns, explained in detail with examplesx