Visitor Design Pattern Tutorial

Visitor Design Pattern TutorialWelcome to my Visitor Design Pattern Tutorial! This is the last part of my design pattern video tutorial.

The Visitor design pattern allows you to add methods to classes of different types without much altering to those classes. You can make completely different methods depending on the class used with this pattern.

With both the video below and the code that follows you should be able to start using this pattern in your code easily.

If you like videos like this, it helps if you tell Google with a click

Share this video if you know someone who may like it

Code from the Video

VISITOR.JAVA

// The visitor pattern is used when you have to perform
// the same action on many objects of different types

interface Visitor {
	
	// Created to automatically use the right 
	// code based on the Object sent
	// Method Overloading
	
	public double visit(Liquor liquorItem);
	
	public double visit(Tobacco tobaccoItem);
	
	public double visit(Necessity necessityItem);
	
}

TAXVISITOR.JAVA

import java.text.DecimalFormat;

// Concrete Visitor Class

class TaxVisitor implements Visitor {
	
	// This formats the item prices to 2 decimal places
	
	DecimalFormat df = new DecimalFormat("#.##");

	// This is created so that each item is sent to the
	// right version of visit() which is required by the
	// Visitor interface and defined below
	
	public TaxVisitor() {
	}
	
	// Calculates total price based on this being taxed
	// as a liquor item
	
	public double visit(Liquor liquorItem) {
		System.out.println("Liquor Item: Price with Tax");
		return Double.parseDouble(df.format((liquorItem.getPrice() * .18) + liquorItem.getPrice()));
	}
	
	// Calculates total price based on this being taxed
	// as a tobacco item
		
	public double visit(Tobacco tobaccoItem) {
		System.out.println("Tobacco Item: Price with Tax");
		return Double.parseDouble(df.format((tobaccoItem.getPrice() * .32) + tobaccoItem.getPrice()));
	}
	
	// Calculates total price based on this being taxed
	// as a necessity item
		
	public double visit(Necessity necessityItem) {
		System.out.println("Necessity Item: Price with Tax");
		return Double.parseDouble(df.format(necessityItem.getPrice()));
	}

}

VISITABLE.JAVA

interface Visitable {

	// Allows the Visitor to pass the object so
	// the right operations occur on the right 
	// type of object.
	
	// accept() is passed the same visitor object
	// but then the method visit() is called using 
	// the visitor object. The right version of visit()
	// is called because of method overloading
	
	public double accept(Visitor visitor);
	
}

LIQUOR.JAVA

class Liquor implements Visitable {
	
	private double price;

	Liquor(double item) {
		price = item;
	}

	public double accept(Visitor visitor) {
		return visitor.visit(this);
	}

	public double getPrice() {
		return price;
	}
	
}

NECESSITY.JAVA

class Necessity implements Visitable {
	
	private double price;

	Necessity(double item) {
		price = item;
	}

	public double accept(Visitor visitor) {
		return visitor.visit(this);
	}

	public double getPrice() {
		return price;
	}
	
}

TOBACCO.JAVA

class Tobacco implements Visitable {
	
	private double price;

	Tobacco(double item) {
		price = item;
	}

	public double accept(Visitor visitor) {
		return visitor.visit(this);
	}

	public double getPrice() {
		return price;
	}
	
}

TAXHOLIDAYVISITOR.JAVA

import java.text.DecimalFormat;

// Concrete Visitor Class

class TaxHolidayVisitor implements Visitor {
	
	// This formats the item prices to 2 decimal places
	
	DecimalFormat df = new DecimalFormat("#.##");

	// This is created so that each item is sent to the
	// right version of visit() which is required by the
	// Visitor interface and defined below
	
	public TaxHolidayVisitor() {
	}
	
	// Calculates total price based on this being taxed
	// as a liquor item
	
	public double visit(Liquor liquorItem) {
		System.out.println("Liquor Item: Price with Tax");
		return Double.parseDouble(df.format((liquorItem.getPrice() * .10) + liquorItem.getPrice()));
	}
	
	// Calculates total price based on this being taxed
	// as a tobacco item
		
	public double visit(Tobacco tobaccoItem) {
		System.out.println("Tobacco Item: Price with Tax");
		return Double.parseDouble(df.format((tobaccoItem.getPrice() * .30) + tobaccoItem.getPrice()));
	}
	
	// Calculates total price based on this being taxed
	// as a necessity item
		
	public double visit(Necessity necessityItem) {
		System.out.println("Necessity Item: Price with Tax");
		return Double.parseDouble(df.format(necessityItem.getPrice()));
	}

}

VISITORTEST.JAVA

public class VisitorTest {
	public static void main(String[] args) {
		
		TaxVisitor taxCalc = new TaxVisitor();
		TaxHolidayVisitor taxHolidayCalc = new TaxHolidayVisitor();
		
		Necessity milk = new Necessity(3.47);
		Liquor vodka = new Liquor(11.99);
		Tobacco cigars = new Tobacco(19.99);
		
		System.out.println(milk.accept(taxCalc) + "\n");
		System.out.println(vodka.accept(taxCalc) + "\n");
		System.out.println(cigars.accept(taxCalc) + "\n");
		
		System.out.println("TAX HOLIDAY PRICES\n");

		System.out.println(milk.accept(taxHolidayCalc) + "\n");
		System.out.println(vodka.accept(taxHolidayCalc) + "\n");
		System.out.println(cigars.accept(taxHolidayCalc) + "\n");

	}
}

36 Responses to “Visitor Design Pattern Tutorial”

  1. Joy says:

    Good job!! code and video together is a nice approach, thanks.

  2. Paul says:

    Thank you so much for the video! You cleared up A LOT for me.

    I’m still stuck on one thing though…I still don’t understand what VISITABLE.JAVA does. I read the comments in the source code, but I still don’t get it 🙁

    • admin says:

      You’re very welcome. Think of visitable as a way to sneak into the classes that implement it. It would be like if you knew someone hid a key to their house under their door mat. You can go in anytime you want. visitable places a method accept in the class. Then you’ll be able to call visitor.visit(this) when ever you like, which passes the class object that implements visitable with (this) to the visit method. Because I have 3 visit methods the right one is executed depending on whether a Liquor, Tobacco, or Necessity object is passed. Does that help. It is all about placing a method call in an object and then executing the right method using method overloading

  3. MReddy says:

    Dear Derek,
    Thanks for the effort that you are putting to create all these videos and articles which are very informative.
    Can you also consider creating articles/videos on Core J2EE Design Patterns which also would be very helpful for many, across the world?

    • Derek Banas says:

      Thank you 🙂 Yes I will cover J2EE and the patterns specific to it and all of the frameworks as well. I’ll do my best to make videos as quickly as possible

  4. Frank says:

    Thanks For all the videos..Very Informative..Removes any confusion..
    Thanks Again..
    Frank

  5. boris says:

    cant wait to look over all of these videos..im excited!

  6. Raj says:

    In the VisitorTest class you have called the appropriate methods by milk.accept(taxCalc) but that can be also called like taxCalc.visit(milk/vodka/cigars) or taxHolidayCalc .visit(milk/vodka/cigars) then what is the advantage here?

    ————————————–
    public class VisitorTest {
    public static void main(String[] args) {

    TaxVisitor taxCalc = new TaxVisitor();
    TaxHolidayVisitor taxHolidayCalc = new TaxHolidayVisitor();

    Necessity milk = new Necessity(3.47);
    Liquor vodka = new Liquor(11.99);
    Tobacco cigars = new Tobacco(19.99);

    System.out.println(milk.accept(taxCalc) + “\n”);
    System.out.println(vodka.accept(taxCalc) + “\n”);
    System.out.println(cigars.accept(taxCalc) + “\n”);

    System.out.println(“TAX HOLIDAY PRICES\n”);

    System.out.println(milk.accept(taxHolidayCalc) + “\n”);
    System.out.println(vodka.accept(taxHolidayCalc) + “\n”);
    System.out.println(cigars.accept(taxHolidayCalc) + “\n”);

    }
    }

  7. Roopa says:

    Fantastic video on design patters. Made me understand the patterns in detail . Great job !

  8. Are you also gonna make tutorials on Frameworks Like strut or spring and hibernate/JPI for developing enterprise level applications???

  9. Ariel says:

    Hi Derek, thanks so much for all these videos! greatly helping me 🙂 is there a package with all source codes from the design pattern videos?

  10. Vishwanath says:

    Hi Derek,

    I’ve been learning so much from these design patterns videos and thank you so much for it ! The content is just great !

    As for this visitor pattern example, the visit() and accept() methods have a ‘double’ return value. But doesn’t that restrict the kind of future-operations that could be added ?

    A few other examples that I went through have the visit() and accept() methods as void-methods and store the results in instance variables within the visitor. This second approach looks to be more flexible.

    So, If I were to add a DescriptionVisitor that could visit Liquor,Tobacco and Necessity classes, I wouldn’t have to add a method like:
    String take(Visitor)
    in each of those Visitable classes.

    Your thoughts ?

    Cheers,
    Vishwa

    • Derek Banas says:

      Hi Vishwa,

      That is a very good point and I agree with you. The only reason why I locked them down and removed flexibility was for tutorial reasons. I have to constantly think about 2 things when I’m making these videos. First I need them to be accurate. Secondly I need them to be as easy to understand as possible.

      In my mind making something easier to understand normally forces me to make code that is less flexible. That is a shortcoming that I’m working on. That is why I constantly try to improve and I very much welcome great insights like you have provided here.

      Thank you for helping me make the tutorials better 🙂
      Derek

  11. Praveen Rampally says:

    Hi Derek,
    I went through couple of videos of design patterns and OO design.And as you said in one of the videos i absolutely agree with you saying nobody does this kind of videos on you tube.

    i have a request though if you can do TDD in similar lines of OO design, that would do world of good. As i thought you would be the best person to do such stuff once i saw your OO design videos. please take a use case / user story and if you can cover end – end like how you design and related thought process before you start with initial test. as i browsed a lot and see no body as ever provided such videos on TDD. every body say a problem and show the tests. but no body tell what is the design / thought process lead them to write such tests in front. hope i didn’t confused you.

    and thanks a ton for all you work.

    • Derek Banas says:

      Hi Praveen,

      I did my best to explain test driven design in my Object Oriented Design tutorial. Of course it doesn’t really work unless you get a bunch of people in a room in front of a white board and work through the “Real World” process. I have been trying to get people to allow me to video tape that process. As I’m sure you know it mainly involves people throwing out ideas and then we run to our computers and work them out. Then back to the white board over and over again. It is a ton of fun if you are on a good team.

      I’ll do my best to get that on video. Thank you for the great request 🙂

  12. Andre says:

    Hi Derek,

    Great tutorials, thank you very much!

    Is there any reason why the Visitable isn’t an abstract class holding the visit method?

    public abstract class Visitable {
    public double accept(Visitor visitor) {
    return visitor.visit(this);
    }
    }

    Thanks

Trackbacks/Pingbacks

  1. Visitor Pattern Java Tutorial | Video Tutorials - TutsTV - [...] Source Code [...]

Leave a Reply

Your email address will not be published.

Google+