I had been reading about Design Patterns a while ago, and later dropped it after reading a few designs for reasons unknown. I carried on with my programming after that. Now when I look at the code that I’ve written(after reading the Design Patterns) I can see that I have unknowingly put some of the Design Patterns I had read about into the code I have done! Wow! :) Since it has helped me to code better I have decided to learn/revise atleast one new pattern once in a few days(or weeks for that matter ;) as am a bit lazy!).

Here is the repo I created to track my experiment with Design Patterns.

Read about Visitor pattern here and here.

Classification : Behavioral Pattern

Check out the code here.

Visitor pattern is used to parse through(or visit, in other words) through collections. Collections are made up of entities which themselves can be collections or simple elements.

Imagine a big colony. It has got some houses. And there are even smaller colonies. The big-colony and everthing it has (houses and smaller colonies) accepts visitors(athidi-devo-bhav!) with a very good heart. The colony in programming terms is a collection and houses are elements. Visitor is an object that visits the colony.

Now the colony and houses should declare that they accepts visitors. So they should implement ‘Visitable’ interface which tells that they will have accept(Visitor).

Also our visitor should tell that he is really a ‘Visitor’ and not a thief, so he must implement ‘Visitor’ interface which tells that he’ll visit(Colony) and visit(House). What a visitor will do after visiting a house or colony is upto him, the ‘Visitor’ tag just tells that he is a legitimate visitor.

There are two flavors of Visitor Pattern:

  1. Visitable can control where the visitor goes next.
Suppose we have a big colony and a visitor. We ask the big-colony to accept the visitor. The colony will then decide where the visitor should go next. It may send the visitor to all the houses first or it can tell the visitor to visit the smaller colonies first.

accept() for colony:

public void accept(Visitor visitor) {
    visitor.visit(this);
    for(House house : houses) {
        house.accept(visitor);
    }
    for(Colony colony : colonies) {
        colony.accept(visitor);
    }
}

visit() of visitor:

public void visit(Visitable visitable) {

	if(visitable instanceof House) {
		House house = (House) visitable;
		System.out.println("Visited House : " + house.getName());
	} else if(visitable instanceof Colony) {
		Colony colony = (Colony) visitable;
		System.out.println("Visited colony : " + colony.getName());
	}
}

  1. Visitor controls where he goes next
Suppose we have a big colony and a visitor. We ask the big-colony to accept the visitor. Once the visitor is inside he decides where to go next. In this case there is more flexibility and power for the visitors.

accept() for colony:

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

visit() of visitor:

public void visit(Visitable visitable) {

	if(visitable instanceof House) {
		House house = (House) visitable;
		System.out.println("Visited House : " + house.getName());
	} else if(visitable instanceof Colony) {
		Colony colony = (Colony) visitable;
		System.out.println("Visited colony : " + colony.getName());
		for(House h : colony.getHouses()) {
			this.visit(h);
		}
		for(Colony c : colony.getColonies()) {
			this.visit(c);
		}
	}
}

Happy coding :)