Visitor Design Pattern

The Visitor Design Pattern is a behavioral design pattern. It comes in handy when we have to add a capability to an object with minimal change to the existing object structure. It is achieved by simply adding a method to the object that accepts a Visitor object. This would allow the new functionality to “visit” the existing object and get things we need to be done! Doesn’t it sound awesome? Well, let’s not waste any more time – time to dive into the code 🙃

Assume that we are developing software for a company that deals in 3 types products: Petroleum, Furniture and Daily needs. Now, due to the government rules, it needs to implement taxes that calculate the final price of the item using GST.

The interface visitor is used to “visit” the correct method using function overloading.

public interface Visitor {
    double visit(Petroleum petroleum);
    double visit(Furniture furniture);
    double visit(DailyNeeds dailyNeeds);
}

This is the concrete implementation of the Visitor class.

// Adds tax on the price
public class GSTVisitor implements Visitor {
    @Override
    public double visit(Petroleum petroleum) {
        return (petroleum.getPrice() + petroleum.getPrice() * 0.30);
    }

    @Override
    public double visit(Furniture furniture) {
        return (furniture.getPrice() + furniture.getPrice() * 10);
    }

    @Override
    public double visit(DailyNeeds dailyNeeds) {
        return dailyNeeds.getPrice();
    }
}

Next up, we have the Visitable interface which the objects need to implement in order to implement the tax functionality which in turn delegates the tax to GSTVisitor.

public interface Visitable {
    double accept(Visitor visitor);
}

The three classes below implement the Visitable interface and then delegate the tax calculation to GSTVisitor.

public class Petroleum implements Visitable {
    private double price;

    Petroleum(double price) {
        this.price = price;
    }

    public double getPrice() {
        return price;
    }

    @Override
    public double accept(Visitor visitor) {
        return visitor.visit(this);
    }
}
public class Furniture implements Visitable {
    private double price;

    Furniture(double price) {
        this.price = price;
    }

    public double getPrice() {
        return price;
    }

    @Override
    public double accept(Visitor visitor) {
        return visitor.visit(this);
    }
}
public class DailyNeeds implements Visitable {
    private double price;

    DailyNeeds(double price) {
        this.price = price;
    }

    public double getPrice() {
        return price;
    }

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

The code above is tested using this:

public class Main {

    public static void main(String[] args) {
        GSTVisitor GSTVisitor = new GSTVisitor();

        Petroleum diesel = new Petroleum(60);
        Furniture chair = new Furniture(5000);
        DailyNeeds rice = new DailyNeeds(100);

        double ricePrice = rice.accept(GSTVisitor);
        double chairPrice = chair.accept(GSTVisitor);
        double dieselPrice = diesel.accept(GSTVisitor);

        System.out.println("Price of rice: " + ricePrice);
        System.out.println("Price of chair: " + chairPrice);
        System.out.println("Price of diesel: " + dieselPrice);
    }
}

//output
Price of rice: 100.0
Price of chair: 5500.0
Price of diesel: 78.0
No Comments

Post A Comment