Skip to main content

Command Palette

Search for a command to run...

Golang - Visitor Pattern

Updated
3 min read
Golang - Visitor Pattern
M

Senior Freelancer & Technical Lead

Working as a Golang developer since 2020. Working as a mobile developer since 2013.

Focussed on architecture, testability and clean code. Open minded & product driven. Based in Rhede, available world-wide

The Gang of Four design patterns are widely used in software development. One of the most useful ones is the Visitor Pattern. In this article, we will discuss the Visitor Pattern in the context of Golang.

What is the Visitor Pattern?

The Visitor Pattern is a behavioral design pattern that allows us to separate an algorithm from an object structure on which it operates. It is useful when we have a complex object structure and we want to perform some operations on it without changing the classes of the objects in the structure.

How does it work?

The Visitor Pattern works by separating the algorithm from the object structure. To achieve this, we define an interface that represents the algorithm. This interface will have a method for each class in the object structure. Each method will take an instance of the class as an argument. The object structure will also have an interface that defines a method for accepting the visitor. This method will take an instance of the visitor interface as an argument. When the accept method is called, the visitor's corresponding method for the class will be called.

Example

Suppose we have a complex object structure that represents a company's employees. The structure consists of different classes such as Manager, Engineer, and Salesman. We want to calculate the total salary of all employees in the company. We can use the Visitor Pattern to achieve this.

First, we define the Visitor interface:

type Visitor interface {
    VisitManager(manager *Manager)
    VisitEngineer(engineer *Engineer)
    VisitSalesman(salesman *Salesman)
}

Next, we define the Employee interface that defines a method for accepting the visitor:

type Employee interface {
    Accept(visitor Visitor)
}

We then define the different classes in the object structure:

type Manager struct {
    Name string
    Salary float64
}

func (m *Manager) Accept(visitor Visitor) {
    visitor.VisitManager(m)
}

type Engineer struct {
    Name string
    Salary float64
}

func (e *Engineer) Accept(visitor Visitor) {
    visitor.VisitEngineer(e)
}

type Salesman struct {
    Name string
    Salary float64
}

func (s *Salesman) Accept(visitor Visitor) {
    visitor.VisitSalesman(s)
}

Finally, we define the ConcreteVisitor that implements the Visitor interface and performs the desired operation:

type SalaryCalculator struct {
    TotalSalary float64
}

func (s *SalaryCalculator) VisitManager(manager *Manager) {
    s.TotalSalary += manager.Salary
}

func (s *SalaryCalculator) VisitEngineer(engineer *Engineer) {
    s.TotalSalary += engineer.Salary
}

func (s *SalaryCalculator) VisitSalesman(salesman *Salesman) {
    s.TotalSalary += salesman.Salary
}

We can then use the Visitor Pattern to calculate the total salary of all employees:

func main() {
    employees := []Employee{
        &Manager{Name: "John", Salary: 5000},
        &Engineer{Name: "Mary", Salary: 4000},
        &Salesman{Name: "Bob", Salary: 3000},
    }

    calculator := &SalaryCalculator{}
    for _, employee := range employees {
        employee.Accept(calculator)
    }

    fmt.Println("Total salary:", calculator.TotalSalary)
}

Output:

Total salary: 12000

Conclusion

The Visitor Pattern is a powerful design pattern that allows us to separate an algorithm from an object structure. It can be useful in many scenarios where we have a complex object structure and we want to perform some operations on it without changing the classes of the objects in the structure. In Golang, we can easily implement the Visitor Pattern using interfaces and methods.


References

Golang Patterns

Part 2 of 19

Welcome to the Golang Patterns tutorial series! In this series, we will explore the various software patterns that can be applied in Golang to create flexible, scalable, and maintainable software.

Up next

Golang - Template Method Pattern

The Template Method Pattern is a behavioral design pattern that defines the skeleton of an algorithm in a superclass but lets subclasses override specific steps of the algorithm without changing its structure. In other words, the Template Method Patt...