Sunday, August 17, 2014

Visitor Pattern

Visitor pattern provides a way to implement double dispatch in Java. What double dispatch means? Double dispatch in simple terms means, you start with an object->Pass the reference to another object->Another object will do a callback which will land up in the starting object itself. Simple:). The starting object are usually algorithmic objects and the other objects are usually structural objects.

Let's take an example that in an organization we have people with different designation. Different designations are treated in different way. For example, let's say we need to calculate their salaries based on role in a different way. Also we need to calculate the Stocks to be allotted to them based on the designations. Here we have a set of objects, and a set of algorithms.

Now Salary class (Finance department in real life), has all the logic buried in it to. Also the logic of how much stock to allot is buried in StockAllotment class(HR department). And we do not want each individual to calculate theirs salaries or their stocks. That's where Visitor pattern comes into picture.

public interface Employee {
   public void accept(Calculator calculator);
}

public class Manager implements Employee {
public void accept(Calculator calculator) {
calculator.visit(this);
}
}

public class Developer implements Employee {
public void accept(Calculator calculator) {
calculator.visit(this);
}
}
public interface Calculator {
public void visit(Manager manager);
public void visit(Developer developer);
}

public class SalaryCalculator implements Calculator {

@Override
public void visit(Manager manager) {
System.out.println("Salary = Lines of code written");
}

@Override
public void visit(Developer developer) {
System.out.println("Salary = 1/Number of Bugs introduced");
}
}

public class StockCalculator implements Calculator {

@Override
public void visit(Manager manager) {
System.out.println("Stocks = amount of money spend lat year");
}

@Override
public void visit(Developer developer) {
System.out.println("Stocks = Do we need to give them?");
}
}

Now the main class

public class VisitorMain {

public static void main(String[] args) {

List<Employee> employeeList = new ArrayList<Employee>();
employeeList.add(new Developer());
employeeList.add(new Manager());

SalaryCalculator salaryCalculator = new SalaryCalculator();
StockCalculator stockCalculator = new StockCalculator();

for (Employee employee : employeeList) {
employee.accept(salaryCalculator);
employee.accept(stockCalculator);
}
}

}

Notice that we started with Salary Calculator, passed it to an instance of employee and the final call landed back into SalaryCalculator class.

One big disadvantage of Visitor pattern is that if you introduce one more concrete type, than one more call back has to be written in Calculator interface and has to be implemented all through. You can write one more abstract class in between Employee and other concrete class which has the default implementation, and that would shield from a lot of changes. On the positive side, this disadvantage is a great job creator.

Articles on Software Design and Patterns

No comments:

Post a Comment