Visitor pattern is used to move the operation/calculation part from a group of classes to a completely separate(Visitor) class.
This article demonstrates Visitor pattern implementations in Java. Check the following examples.
Examples
Here are a few examples of Visitor pattern implementation in Java-
Example #1: Hosting Cost Calculator
Let’s consider an example of a hosting service, and calculate the total cost of the hosting service used using the visitor pattern.
Service Interface
// Service.java
package com.bigboxcode.designpattern.visitor.hosting;
public interface Service {
double accept(HostingCalculatorVisitor hostingCalculatorVisitor);
}
Compute Service Class
// ComputeService.java
package com.bigboxcode.designpattern.visitor.hosting;
public class ComputeService implements Service {
private final double price = 10.50;
private int quantity;
public ComputeService(int quantity) {
this.quantity = quantity;
}
public double getPrice() {
return price;
}
public int getQuantity() {
return quantity;
}
@Override
public double accept(HostingCalculatorVisitor hostingCalculatorVisitor) {
return hostingCalculatorVisitor.visit(this);
}
}
Database Service Class
// DatabaseService.java
package com.bigboxcode.designpattern.visitor.hosting;
public class DatabaseService implements Service {
private final double price = 100.00;
private final double backPrice = 30.00;
private int quantity;
private boolean backupEnabled = false;
public DatabaseService(int quantity) {
this.quantity = quantity;
}
public DatabaseService(int quantity, boolean backupEnabled) {
this.quantity = quantity;
this.backupEnabled = backupEnabled;
}
public double getPrice() {
return price;
}
public int getQuantity() {
return quantity;
}
public double getBackPrice() {
return backPrice;
}
public boolean isBackupEnabled() {
return backupEnabled;
}
@Override
public double accept(HostingCalculatorVisitor hostingCalculatorVisitor) {
return hostingCalculatorVisitor.visit(this);
}
}
File Storage Service Class
// FileStorageService.java
package com.bigboxcode.designpattern.visitor.hosting;
public class FileStorageService implements Service {
private final double pricePerGB = 1.70;
private int quantity;
public FileStorageService(int quantity) {
this.quantity = quantity;
}
public double getPricePerGB() {
return pricePerGB;
}
public int getQuantity() {
return quantity;
}
@Override
public double accept(HostingCalculatorVisitor hostingCalculatorVisitor) {
return hostingCalculatorVisitor.visit(this);
}
}
Serverless Service Class
// ServerlessService.java
package com.bigboxcode.designpattern.visitor.hosting;
public class ServerlessService implements Service {
private final double hourlyPrice = 0.32;
private int totalHours;
public ServerlessService(int totalHours) {
this.totalHours = totalHours;
}
public double getHourlyPrice() {
return hourlyPrice;
}
public int getTotalHours() {
return totalHours;
}
@Override
public double accept(HostingCalculatorVisitor hostingCalculatorVisitor) {
return hostingCalculatorVisitor.visit(this);
}
}
Container Service Class
// ContainerService.java
package com.bigboxcode.designpattern.visitor.hosting;
public class ContainerService implements Service {
private final double price = 5.60;
private int quantity;
public ContainerService(int quantity) {
this.quantity = quantity;
}
public double getPrice() {
return price;
}
public int getQuantity() {
return quantity;
}
@Override
public double accept(HostingCalculatorVisitor hostingCalculatorVisitor) {
return hostingCalculatorVisitor.visit(this);
}
}
Visitor Interface
// HostingCalculatorVisitor.java
package com.bigboxcode.designpattern.visitor.hosting;
public interface HostingCalculatorVisitor {
double visit(ComputeService computeService);
double visit(ContainerService containerService);
double visit(DatabaseService databaseService);
double visit(FileStorageService fileStorageService);
double visit(ServerlessService serverlessService);
}
Visitor Interface Implementation
// HostingCalculatorVisitorImpl.java
package com.bigboxcode.designpattern.visitor.hosting;
public class HostingCalculatorVisitorImpl implements HostingCalculatorVisitor {
@Override
public double visit(ComputeService computeService) {
return computeService.getPrice() * computeService.getQuantity();
}
@Override
public double visit(ContainerService containerService) {
return containerService.getPrice() * containerService.getQuantity();
}
@Override
public double visit(DatabaseService databaseService) {
double serviceCost = databaseService.getPrice() * databaseService.getQuantity();
double backupCost = 0;
if (databaseService.isBackupEnabled()) {
backupCost = databaseService.getBackPrice() * databaseService.getQuantity();
}
return serviceCost + backupCost;
}
@Override
public double visit(FileStorageService fileStorageService) {
return fileStorageService.getPricePerGB() * fileStorageService.getQuantity();
}
@Override
public double visit(ServerlessService serverlessService) {
return serverlessService.getHourlyPrice() * serverlessService.getHourlyPrice();
}
}
Demo
// Demo.java
package com.bigboxcode.designpattern.visitor.hosting;
public class Demo {
public static void main(String[] args) {
Service[] usedServices = new Service[] {
new ComputeService(3),
new DatabaseService(3, true),
new FileStorageService(120),
new ServerlessService(720),
new ContainerService(2),
};
double totalCost = calculateHostingCost(usedServices);
System.out.println("Total cost of hosting is: " + totalCost);
}
private static double calculateHostingCost(Service[] services) {
HostingCalculatorVisitorImpl hostingCalculatorVisitorImpl = new HostingCalculatorVisitorImpl();
double totalCost = 0;
for (Service service: services) {
totalCost += service.accept(hostingCalculatorVisitorImpl);
}
return totalCost;
}
}
Output
Total cost of hosting is: 636.8024
Source Code
Use the following link to get the source code:
Example | Source Code Link |
---|---|
Example #1: Hosting Cost Calculator | GitHub |
Other Code Implementations
Use the following links to check Visitor pattern implementation in other programming languages.