in design pattern oop object oriented programming refactor cleanc code programming php solid ~ read.

Visitor Design Pattern in Java

In this post we are going to talk about Visitor Pattern in Object Oriented Programming.

What is Visitor Pattern?

In a simple sentence, Visitor Design Pattern is used when you trying to seperate your algorithm from the object.

Why? Sometimes you want to add new features without changing the object structures you've already created. This method helps us focus on Open/Close principle in our design. The visitor classes contain the changes instead of the original object containing them.

That's enough of talking let's see some real code.

The reason I choose Java for demo is cause it is a lot easier and clearer to observe the pattern.

Demo

Let's have a look at the following example without using Visitor Pattern and later on we add it on.

package com.demo.visitor;

import java.util.ArrayList;

public interface IPartsOrder {  
    public double calculateShipping();
}


public class Wheel implements IPartsOrder {  
    @Override
    public double calculateShipping()
    {
        return 1;
    }
}

public class Door implements IPartsOrder {  
    @Override
    public double calculateShipping()
    {
        return 1;
    }
}

public class Engine implements IPartsOrder {  
    @Override
    public double calculateShipping()
    {
        return 1;
    }
}

public class PartsOrder implements IPartsOrder {  
    private List<IPartsOrder> parts = new ArrayList<>;

    public PartsOrder() {}

    public void addPart(IPartsOrder part) {
        parts.add(part);
    }

    public List<IPartsOrder> getParts() {
        return parts;
    }

    public double calculateShipping() {
        double shippingCost;
        for (IPartsOrder part : parts) {
            shippingCost += part.calculateShipping();
        }
        return shippingCost;
    }
}

public class Demo {  
    public static void main(String[] args)
    {
        PartsOrder order = new PartsOrder();
        order.addPart(new Wheel());
        order.addPart(new Door());
        order.addPart(new Engine());

        double shippingCost = order.calculateShipping();

        System.our.println(shippingCost); // 3
    }
}

(Demo.java)

This is quite normal, isn't? I bet you have seen similar code for lie hundreds times before.

Let's see the code that is utilising Visitor Pattern.

package com.demo.visitor;

import java.util.ArrayList;

public interface IPartsOrder {  
    public void accept(IPartsOrderVisitor visitor);
}

public interface IPartsOrderVisitor {  
    void visit(Wheel wheel);
    void visit(Door door);
    void visit(Engine engine);
    void visit(PartsOrder partsOrder);
}

public class Wheel implements IPartsOrder {  
    @Override
    public void accept(IPartsOrderVisitor visotor)
    {
        visotor.visit(this);
    }
}

public class Door implements IPartsOrder {  
    @Override
    public void accept(IPartsOrderVisitor visotor)
    {
        visotor.visit(this);
    }
}

public class Engine implements IPartsOrder {  
    @Override
    public void accept(IPartsOrderVisitor visotor)
    {
        visotor.visit(this);
    }
}

public class PartsOrder implements IPartsOrder {  
    private List<IPartsOrder> parts = new ArrayList<>;

    public PartsOrder() {}

    public void addPart(IPartsOrder part) {
        parts.add(part);
    }

    public List<IPartsOrder> getParts() {
        return parts;
    }

    @Override
    public void accept(IPartsOrderVisitor visitor) {
        for (IPartsOrder part : parts) {
            part.accept(visotor);
        }
        visitor.visit(this);
    }
}

public PartsOrderShippingVisitor implements IPartsOrderVisitor {  
    double shippingAmount = 0;

    @Override
    public void visit(Wheel wheel) {
        shippingAmount += 1;
    }

    @Override
    public void visit(Door door) {
        shippingAmount += 1;
    }

    @Override
    public void visit(Engine engine) {
        shippingAmount += 1;
    }

    @Override
    public void visit(PartsOrder partsOrder) {
        List<IPartsOrder> parts = partsOrder.getParts();
        if (partsOrder.size() > 3) {
            shippingAmount -= 5;
        }
    }
}

public class Demo {  
    public static void main(String[] args)
    {
        PartsOrder order = new PartsOrder();
        order.addPart(new Wheel());
        order.addPart(new Door());
        order.addPart(new Engine());

        order.accept(new PartsOrderShippingVisitor());

        System.our.println(shippingCost); // 3
    }
}

`(Demo.java)

As you can see here the logic used for calculating shipping has been moved out of the PartOrder class into different visitors.

End

If you have any comments or ideas please leave it below. Thanks.

comments powered by Disqus