Saturday, October 13, 2007

Visitor Pattern--How to implement

Today, i want to introduce about Visitor Pattern.

Goal: Why do we have to use Visitor Pattern? The answer is we need to separate the algorithm and the object structure. To see it clearly, we will discuss about it.
The Visitor pattern is also the classic technique for recovering lost type information without resorting to dynamic casts.

In this class diagram, a visitor can be considered as a different algorithm.
A Object Structure is an object which the algorithm work on it. This ObjectStructure has a complex structure and we want to separate the structure from algorithm. To do it, we have to give the algorithm the part of an ObjectStructure. This part of object will do its own task by using the algorithm which give to it.

Example:

interface
Visitor {
   void visit(Wheel wheel);
void visit(Engine engine);
void visit(Body body);
void visit(Car car);
}


interface Visitable {
void accept(Visitor visitor);
}

class Wheel implements Visitable {
private String name;
Wheel(String name) {
this.name = name;
}
String getName() {
return this.name;
}
public void accept(Visitor visitor) {
visitor.visit(this);
}
}

class Engine implements Visitable{
public void accept(Visitor visitor) {
visitor.visit(this);
}
}

class Body implements Visitable{
public void accept(Visitor visitor) {
visitor.visit(this);
}
}

class Car implements Visitable {
private Engine engine = new Engine();
private Body body = new Body();
private Wheel[] wheels
= { new Wheel("front left"), new Wheel("front right"),
new Wheel("back left") , new Wheel("back right") };
public Engine getEngine() {
return this.engine;
}
public Body getBody() {
return this.body;
}
public Wheel[] getWheels() {
return this.wheels;
}
public void accept(Visitor visitor) {
visitor.visit(this);
engine.accept(visitor);
body.accept(visitor);
for(int i = 0; i < class="me1">length; i++) {
Wheel wheel = wheels[i];
wheel.accept(visitor);
}
}
}

class PrintVisitor implements Visitor {

public void visit(Wheel wheel) {
System.out.println("Visiting "+ wheel.getName()
+ " wheel");
}
public void visit(Engine engine) {
System.out.println("Visiting engine");
}
public void visit(Body body) {
System.out.println("Visiting body");
}
public void visit(Car car) {
System.out.println("Visiting car");
}

}

class DoVisitor implements Visitor {
public void visit(Wheel wheel) {
System.out.println("Steering my wheel");
}
public void visit(Engine engine) {
System.out.println("Starting my engine");
}
public void visit(Body body) {
System.out.println("Moving my body");
}
public void visit(Car car) {
System.out.println("Vroom!");
}
}

public class VisitorDemo {
static public void main(String[] args){
Car car = new Car();
Visitor visitor = new PrintVisitor();
Visitor doVisitor = new DoVisitor();
car.accept(visitor);
car.accept(doVisitor);
}
}
As we can see, a car has some part: Wheel, Engine, Body, Car.
The first algorithm: PrintVisitor( Print) and the second algorithm has different
behavior to four part of car and do not care about the structure of Car ( refer to
the main function). It is very important when implement the complex algorithm.
It is also useful when maintaining class. We can easily add new algorithm without
affecting the others algorithm and object structure.

Google